Add per-agent skill workspaces and TraderView management

This commit is contained in:
2026-03-17 13:55:14 +08:00
parent 1f5ee3698e
commit 2daf5717ba
35 changed files with 4774 additions and 331 deletions

View File

@@ -0,0 +1,247 @@
import React from 'react';
export default function RuntimeSettingsPanel({
isOpen,
isConnected,
isSaving,
feedback,
runtimeConfig,
scheduleMode,
intervalMinutes,
triggerTime,
maxCommCycles,
onToggle,
onClose,
onScheduleModeChange,
onIntervalMinutesChange,
onTriggerTimeChange,
onMaxCommCyclesChange,
onSave,
onRestoreDefaults
}) {
return (
<div style={{ display: 'flex', alignItems: 'center', gap: 8, minWidth: 0, position: 'relative' }}>
<button
onClick={onToggle}
style={{
padding: '6px 10px',
borderRadius: 4,
border: '1px solid #333333',
background: isOpen ? '#1E1E1E' : '#111111',
color: '#FFFFFF',
fontSize: '11px',
fontWeight: 700,
letterSpacing: '0.6px',
cursor: 'pointer',
whiteSpace: 'nowrap'
}}
>
运行设置
</button>
{isOpen && (
<div style={{
position: 'absolute',
top: 'calc(100% + 10px)',
right: 0,
width: 320,
maxWidth: 'min(320px, 92vw)',
padding: '14px',
borderRadius: 8,
border: '1px solid #D9D9D9',
background: '#FFFFFF',
boxShadow: '0 12px 36px rgba(0, 0, 0, 0.14)',
zIndex: 40,
display: 'grid',
gap: 12
}}>
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', gap: 12 }}>
<div>
<div style={{ fontSize: '12px', fontWeight: 700, color: '#111111', letterSpacing: '0.3px' }}>
运行设置
</div>
<div style={{ fontSize: '11px', color: '#666666', marginTop: 2 }}>
保存后立即热更新当前运行中的调度参数
</div>
</div>
<button
onClick={onClose}
style={{
border: 'none',
background: 'transparent',
color: '#666666',
cursor: 'pointer',
fontSize: '14px',
lineHeight: 1
}}
>
×
</button>
</div>
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 8 }}>
<label style={{ display: 'grid', gap: 4 }}>
<span style={{ fontSize: '10px', color: '#4B5563', fontWeight: 700 }}>调度模式</span>
<select
value={scheduleMode}
onChange={(e) => onScheduleModeChange(e.target.value)}
style={{
padding: '9px 10px',
borderRadius: 6,
border: '1px solid #D0D7DE',
background: '#FFFFFF',
color: '#111111',
fontSize: '12px'
}}
>
<option value="daily">daily</option>
<option value="intraday">intraday</option>
</select>
</label>
<label style={{ display: 'grid', gap: 4 }}>
<span style={{ fontSize: '10px', color: '#4B5563', fontWeight: 700 }}>间隔(分钟)</span>
<input
type="number"
min="1"
value={intervalMinutes}
onChange={(e) => onIntervalMinutesChange(e.target.value)}
style={{
padding: '9px 10px',
borderRadius: 6,
border: '1px solid #D0D7DE',
background: '#FFFFFF',
color: '#111111',
fontSize: '12px',
fontFamily: '"Courier New", monospace'
}}
/>
</label>
</div>
<label style={{ display: 'grid', gap: 4 }}>
<span style={{ fontSize: '10px', color: '#4B5563', fontWeight: 700 }}>Daily 时间 (NYSE)</span>
<input
type="time"
value={triggerTime}
onChange={(e) => onTriggerTimeChange(e.target.value)}
disabled={scheduleMode !== 'daily'}
style={{
padding: '9px 10px',
borderRadius: 6,
border: '1px solid #D0D7DE',
background: scheduleMode === 'daily' ? '#FFFFFF' : '#F3F4F6',
color: '#111111',
fontSize: '12px',
fontFamily: '"Courier New", monospace'
}}
/>
</label>
<label style={{ display: 'grid', gap: 4 }}>
<span style={{ fontSize: '10px', color: '#4B5563', fontWeight: 700 }}>讨论轮数上限</span>
<input
type="number"
min="1"
value={maxCommCycles}
onChange={(e) => onMaxCommCyclesChange(e.target.value)}
style={{
padding: '9px 10px',
borderRadius: 6,
border: '1px solid #D0D7DE',
background: '#FFFFFF',
color: '#111111',
fontSize: '12px',
fontFamily: '"Courier New", monospace'
}}
/>
</label>
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 8 }}>
<button
onClick={onRestoreDefaults}
style={{
padding: '9px 12px',
borderRadius: 6,
border: '1px solid #D0D7DE',
background: '#FFFFFF',
color: '#111111',
fontSize: '11px',
fontWeight: 700,
cursor: 'pointer'
}}
>
恢复默认
</button>
<button
onClick={onSave}
disabled={!isConnected || isSaving}
style={{
padding: '9px 14px',
borderRadius: 6,
border: '1px solid #1565C0',
background: isConnected && !isSaving ? '#0D47A1' : '#94A3B8',
color: '#FFFFFF',
fontSize: '11px',
fontWeight: 700,
letterSpacing: '0.4px',
cursor: isConnected && !isSaving ? 'pointer' : 'not-allowed'
}}
>
{isSaving ? '保存中' : '保存运行配置'}
</button>
</div>
{feedback && (
<span style={{
color: feedback.type === 'success' ? '#00C853' : '#FF5252',
fontSize: '11px',
fontFamily: '"Courier New", monospace'
}}>
{feedback.text}
</span>
)}
{runtimeConfig && (
<div style={{
borderTop: '1px solid #E5E7EB',
paddingTop: 12,
display: 'grid',
gap: 8
}}>
<div>
<div style={{ fontSize: '12px', fontWeight: 700, color: '#111111', letterSpacing: '0.3px' }}>
当前生效配置
</div>
<div style={{ fontSize: '11px', color: '#666666', marginTop: 2 }}>
这里显示当前 run 已加载并生效的参数
</div>
</div>
<div style={{
border: '1px solid #E5E7EB',
background: '#F8FAFC',
borderRadius: 6,
padding: '10px 12px',
display: 'grid',
gap: 6,
fontSize: '11px',
fontFamily: '"Courier New", monospace',
color: '#111111'
}}>
<div>tickers: {(runtimeConfig.tickers || []).join(', ') || '-'}</div>
<div>schedule_mode: {runtimeConfig.schedule_mode || '-'}</div>
<div>interval_minutes: {runtimeConfig.interval_minutes ?? '-'}</div>
<div>trigger_time: {runtimeConfig.trigger_time || '-'}</div>
<div>max_comm_cycles: {runtimeConfig.max_comm_cycles ?? '-'}</div>
<div>initial_cash: {runtimeConfig.initial_cash ?? '-'}</div>
<div>margin_requirement: {runtimeConfig.margin_requirement ?? '-'}</div>
<div>enable_memory: {String(runtimeConfig.enable_memory ?? false)}</div>
</div>
</div>
)}
</div>
)}
</div>
);
}