This commit is contained in:
icy
2025-11-01 20:09:17 +08:00
13 changed files with 850 additions and 223 deletions

View File

@@ -18,12 +18,6 @@ function getModelDisplayName(modelId: string): string {
return 'Qwen';
case 'claude':
return 'Claude';
case 'gpt4':
case 'gpt-4':
return 'GPT-4';
case 'gpt3.5':
case 'gpt-3.5':
return 'GPT-3.5';
default:
return modelId.toUpperCase();
}
@@ -134,7 +128,7 @@ export function AITradersPage({ onTraderSelect }: AITradersPageProps) {
const handleCreateTrader = async (data: CreateTraderRequest) => {
try {
const model = allModels?.find(m => m.provider === data.ai_model_id);
const model = allModels?.find(m => m.id === data.ai_model_id);
const exchange = allExchanges?.find(e => e.id === data.exchange_id);
if (!model?.enabled) {
@@ -171,7 +165,7 @@ export function AITradersPage({ onTraderSelect }: AITradersPageProps) {
if (!editingTrader) return;
try {
const model = enabledModels?.find(m => m.provider === data.ai_model_id);
const model = enabledModels?.find(m => m.id === data.ai_model_id);
const exchange = enabledExchanges?.find(e => e.id === data.exchange_id);
if (!model) {
@@ -1083,7 +1077,7 @@ function ModelConfigModal({
type="text"
value={modelName}
onChange={(e) => setModelName(e.target.value)}
placeholder="例如: deepseek-chat, qwen-plus, gpt-4"
placeholder="例如: deepseek-chat, qwen-max, gpt-5"
className="w-full px-3 py-2 rounded"
style={{ background: '#0B0E11', border: '1px solid #2B3139', color: '#EAECEF' }}
/>

View File

@@ -17,6 +17,7 @@ interface TraderConfigData {
trading_symbols: string;
custom_prompt: string;
override_base_prompt: boolean;
system_prompt_template: string;
is_cross_margin: boolean;
use_coin_pool: boolean;
use_oi_top: boolean;
@@ -51,6 +52,7 @@ export function TraderConfigModal({
trading_symbols: '',
custom_prompt: '',
override_base_prompt: false,
system_prompt_template: 'default',
is_cross_margin: true,
use_coin_pool: false,
use_oi_top: false,
@@ -60,6 +62,7 @@ export function TraderConfigModal({
const [availableCoins, setAvailableCoins] = useState<string[]>([]);
const [selectedCoins, setSelectedCoins] = useState<string[]>([]);
const [showCoinSelector, setShowCoinSelector] = useState(false);
const [promptTemplates, setPromptTemplates] = useState<{name: string}[]>([]);
useEffect(() => {
if (traderData) {
@@ -72,19 +75,27 @@ export function TraderConfigModal({
} else if (!isEditMode) {
setFormData({
trader_name: '',
ai_model: availableModels[0]?.provider || '',
ai_model: availableModels[0]?.id || '',
exchange_id: availableExchanges[0]?.id || '',
btc_eth_leverage: 5,
altcoin_leverage: 3,
trading_symbols: '',
custom_prompt: '',
override_base_prompt: false,
system_prompt_template: 'default',
is_cross_margin: true,
use_coin_pool: false,
use_oi_top: false,
initial_balance: 1000,
});
}
// 确保旧数据也有默认的 system_prompt_template
if (traderData && !traderData.system_prompt_template) {
setFormData(prev => ({
...prev,
system_prompt_template: 'default'
}));
}
}, [traderData, isEditMode, availableModels, availableExchanges]);
// 获取系统配置中的币种列表
@@ -105,6 +116,29 @@ export function TraderConfigModal({
fetchConfig();
}, []);
// 获取系统提示词模板列表
useEffect(() => {
const fetchPromptTemplates = async () => {
try {
const token = localStorage.getItem('token');
const response = await fetch('/api/prompt-templates', {
headers: {
'Authorization': `Bearer ${token}`
}
});
const data = await response.json();
if (data.templates) {
setPromptTemplates(data.templates);
}
} catch (error) {
console.error('Failed to fetch prompt templates:', error);
// 使用默认模板列表
setPromptTemplates([{name: 'default'}, {name: 'aggressive'}]);
}
};
fetchPromptTemplates();
}, []);
// 当选择的币种改变时,更新输入框
useEffect(() => {
const symbolsString = selectedCoins.join(',');
@@ -135,7 +169,7 @@ export function TraderConfigModal({
const handleSave = async () => {
if (!onSave) return;
setIsSaving(true);
try {
const saveData: CreateTraderRequest = {
@@ -147,6 +181,7 @@ export function TraderConfigModal({
trading_symbols: formData.trading_symbols,
custom_prompt: formData.custom_prompt,
override_base_prompt: formData.override_base_prompt,
system_prompt_template: formData.system_prompt_template,
is_cross_margin: formData.is_cross_margin,
use_coin_pool: formData.use_coin_pool,
use_oi_top: formData.use_oi_top,
@@ -217,7 +252,7 @@ export function TraderConfigModal({
className="w-full px-3 py-2 bg-[#0B0E11] border border-[#2B3139] rounded text-[#EAECEF] focus:border-[#F0B90B] focus:outline-none"
>
{availableModels.map(model => (
<option key={model.id} value={model.provider}>
<option key={model.id} value={model.id}>
{getShortName(model.name || model.id).toUpperCase()}
</option>
))}
@@ -394,6 +429,27 @@ export function TraderConfigModal({
💬
</h3>
<div className="space-y-4">
{/* 系统提示词模板选择 */}
<div>
<label className="text-sm text-[#EAECEF] block mb-2"></label>
<select
value={formData.system_prompt_template}
onChange={(e) => handleInputChange('system_prompt_template', e.target.value)}
className="w-full px-3 py-2 bg-[#0B0E11] border border-[#2B3139] rounded text-[#EAECEF] focus:border-[#F0B90B] focus:outline-none"
>
{promptTemplates.map(template => (
<option key={template.name} value={template.name}>
{template.name === 'default' ? 'Default (默认稳健)' :
template.name === 'aggressive' ? 'Aggressive (激进)' :
template.name.charAt(0).toUpperCase() + template.name.slice(1)}
</option>
))}
</select>
<p className="text-xs text-[#848E9C] mt-1">
</p>
</div>
<div className="flex items-center gap-3">
<input
type="checkbox"