([])
const ftError = ref('')
const ftLogEl = ref(null)
+const runCancelled = ref(false)
+const ftCancelled = ref(false)
+
+async function cancelBenchmark() {
+ await fetch('/api/benchmark/cancel', { method: 'POST' }).catch(() => {})
+}
+
+async function cancelFinetune() {
+ await fetch('/api/finetune/cancel', { method: 'POST' }).catch(() => {})
+}
+
// ββ Derived ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
const modelNames = computed(() => Object.keys(results.value?.models ?? {}))
const modelCount = computed(() => modelNames.value.length)
@@ -328,6 +353,7 @@ function startBenchmark() {
running.value = true
runLog.value = []
runError.value = ''
+ runCancelled.value = false
const url = `/api/benchmark/run${includeSlow.value ? '?include_slow=true' : ''}`
useApiSSE(
@@ -341,6 +367,10 @@ function startBenchmark() {
if (event.type === 'error' && typeof event.message === 'string') {
runError.value = event.message
}
+ if (event.type === 'cancelled') {
+ running.value = false
+ runCancelled.value = true
+ }
},
async () => {
running.value = false
@@ -363,6 +393,7 @@ function startFinetune() {
ftRunning.value = true
ftLog.value = []
ftError.value = ''
+ ftCancelled.value = false
const params = new URLSearchParams({ model: ftModel.value, epochs: String(ftEpochs.value) })
useApiSSE(
@@ -376,6 +407,10 @@ function startFinetune() {
if (event.type === 'error' && typeof event.message === 'string') {
ftError.value = event.message
}
+ if (event.type === 'cancelled') {
+ ftRunning.value = false
+ ftCancelled.value = true
+ }
},
async () => {
ftRunning.value = false
@@ -453,6 +488,22 @@ onMounted(() => {
.btn-run:disabled { opacity: 0.5; cursor: not-allowed; }
.btn-run:not(:disabled):hover { opacity: 0.85; }
+.btn-cancel {
+ padding: 0.45rem 0.9rem;
+ background: transparent;
+ border: 1px solid var(--color-text-secondary, #6b7a99);
+ color: var(--color-text-secondary, #6b7a99);
+ border-radius: 0.4rem;
+ font-size: 0.85rem;
+ font-weight: 500;
+ cursor: pointer;
+ transition: background 0.15s;
+}
+
+.btn-cancel:hover {
+ background: color-mix(in srgb, var(--color-text-secondary, #6b7a99) 12%, transparent);
+}
+
/* ββ Run log ββββββββββββββββββββββββββββββββββββββββββββββ */
.run-log {
border: 1px solid var(--color-border, #d0d7e8);