| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869 |
- import { useState } from 'react'
- import api, { DeployResponse } from '../api/client'
- export function Deployment() {
- const [jobId, setJobId] = useState('')
- const [mergeWithBase, setMergeWithBase] = useState(false)
- const [exportFormat, setExportFormat] = useState('safetensors')
- const [running, setRunning] = useState(false)
- const [result, setResult] = useState<DeployResponse | null>(null)
- const handleExport = () => {
- if (!jobId.trim()) return
- setRunning(true)
- api.deployment.export({
- job_id: jobId,
- merge_with_base: mergeWithBase,
- export_format: exportFormat,
- })
- .then(setResult)
- .catch(console.error)
- .finally(() => setRunning(false))
- }
- return (
- <div>
- <h1>部署</h1>
- <div style={{ marginTop: 16, background: '#fff', borderRadius: 8, padding: 20, boxShadow: '0 1px 3px rgba(0,0,0,0.1)' }}>
- <h2 style={{ margin: '0 0 16px', fontSize: 16 }}>导出 Adapter</h2>
- <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: 12, alignItems: 'end' }}>
- <div>
- <label style={{ display: 'block', fontSize: 12, color: '#666', marginBottom: 4 }}>训练任务 ID</label>
- <input value={jobId} onChange={e => setJobId(e.target.value)} placeholder="任务 ID" style={{ width: '100%', padding: '6px 8px', borderRadius: 4, border: '1px solid #ccc', boxSizing: 'border-box' }} />
- </div>
- <div>
- <label style={{ display: 'block', fontSize: 12, color: '#666', marginBottom: 4 }}>导出格式</label>
- <select value={exportFormat} onChange={e => setExportFormat(e.target.value)} style={{ width: '100%', padding: '6px 8px', borderRadius: 4, border: '1px solid #ccc', boxSizing: 'border-box' }}>
- <option value="safetensors">SafeTensors</option>
- <option value="gguf">GGUF</option>
- </select>
- </div>
- <div>
- <label style={{ display: 'flex', alignItems: 'center', gap: 6, fontSize: 13, cursor: 'pointer' }}>
- <input type="checkbox" checked={mergeWithBase} onChange={e => setMergeWithBase(e.target.checked)} />
- 合并基础模型
- </label>
- </div>
- </div>
- <button
- onClick={handleExport}
- disabled={running}
- style={{ marginTop: 16, padding: '8px 24px', borderRadius: 4, border: 'none', background: '#e94560', color: '#fff', cursor: 'pointer', opacity: running ? 0.6 : 1 }}
- >
- {running ? '导出中...' : '开始导出'}
- </button>
- </div>
- {result && (
- <div style={{ marginTop: 24, background: '#fff', borderRadius: 8, padding: 20, boxShadow: '0 1px 3px rgba(0,0,0,0.1)' }}>
- <h3>导出状态</h3>
- <p><strong>任务 ID:</strong> {result.job_id}</p>
- <p><strong>状态:</strong> <span style={{ color: result.error ? '#e94560' : '#4caf50' }}>{result.status}</span></p>
- {result.output_path && <p><strong>输出路径:</strong> {result.output_path}</p>}
- {result.error && <p style={{ color: '#e94560' }}><strong>错误:</strong> {result.error}</p>}
- </div>
- )}
- </div>
- )
- }
|