feat: useSftStore — SftQueueItem type and Pinia store
This commit is contained in:
parent
b6d45c746c
commit
9c11916d81
2 changed files with 133 additions and 0 deletions
75
web/src/stores/sft.test.ts
Normal file
75
web/src/stores/sft.test.ts
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
import { setActivePinia, createPinia } from 'pinia'
|
||||
import { useSftStore } from './sft'
|
||||
import type { SftQueueItem } from './sft'
|
||||
import { beforeEach, describe, it, expect } from 'vitest'
|
||||
|
||||
const MOCK_ITEM: SftQueueItem = {
|
||||
id: 'abc',
|
||||
source: 'cf-orch-benchmark',
|
||||
benchmark_run_id: 'run1',
|
||||
timestamp: '2026-04-07T10:00:00Z',
|
||||
status: 'needs_review',
|
||||
prompt_messages: [
|
||||
{ role: 'system', content: 'You are a coding assistant.' },
|
||||
{ role: 'user', content: 'Write a Python add function.' },
|
||||
],
|
||||
model_response: 'def add(a, b): return a - b',
|
||||
corrected_response: null,
|
||||
quality_score: 0.2,
|
||||
failure_reason: 'pattern_match: 0/2 matched',
|
||||
task_id: 'code-fn',
|
||||
task_type: 'code',
|
||||
task_name: 'Code: Write a Python function',
|
||||
model_id: 'Qwen/Qwen2.5-3B',
|
||||
model_name: 'Qwen2.5-3B',
|
||||
node_id: 'heimdall',
|
||||
gpu_id: 0,
|
||||
tokens_per_sec: 38.4,
|
||||
}
|
||||
|
||||
describe('useSftStore', () => {
|
||||
beforeEach(() => setActivePinia(createPinia()))
|
||||
|
||||
it('starts with empty queue', () => {
|
||||
const store = useSftStore()
|
||||
expect(store.queue).toEqual([])
|
||||
expect(store.current).toBeNull()
|
||||
})
|
||||
|
||||
it('current returns first item', () => {
|
||||
const store = useSftStore()
|
||||
store.queue = [MOCK_ITEM]
|
||||
expect(store.current?.id).toBe('abc')
|
||||
})
|
||||
|
||||
it('removeCurrentFromQueue removes first item', () => {
|
||||
const store = useSftStore()
|
||||
const second = { ...MOCK_ITEM, id: 'def' }
|
||||
store.queue = [MOCK_ITEM, second]
|
||||
store.removeCurrentFromQueue()
|
||||
expect(store.queue[0].id).toBe('def')
|
||||
})
|
||||
|
||||
it('restoreItem adds to front of queue', () => {
|
||||
const store = useSftStore()
|
||||
const second = { ...MOCK_ITEM, id: 'def' }
|
||||
store.queue = [second]
|
||||
store.restoreItem(MOCK_ITEM)
|
||||
expect(store.queue[0].id).toBe('abc')
|
||||
expect(store.queue[1].id).toBe('def')
|
||||
})
|
||||
|
||||
it('setLastAction records the action', () => {
|
||||
const store = useSftStore()
|
||||
store.setLastAction('discard', MOCK_ITEM)
|
||||
expect(store.lastAction?.type).toBe('discard')
|
||||
expect(store.lastAction?.item.id).toBe('abc')
|
||||
})
|
||||
|
||||
it('clearLastAction nulls lastAction', () => {
|
||||
const store = useSftStore()
|
||||
store.setLastAction('flag', MOCK_ITEM)
|
||||
store.clearLastAction()
|
||||
expect(store.lastAction).toBeNull()
|
||||
})
|
||||
})
|
||||
58
web/src/stores/sft.ts
Normal file
58
web/src/stores/sft.ts
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
// src/stores/sft.ts
|
||||
import { defineStore } from 'pinia'
|
||||
import { computed, ref } from 'vue'
|
||||
|
||||
export interface SftQueueItem {
|
||||
id: string
|
||||
source: 'cf-orch-benchmark'
|
||||
benchmark_run_id: string
|
||||
timestamp: string
|
||||
status: 'needs_review' | 'approved' | 'discarded' | 'model_rejected'
|
||||
prompt_messages: { role: string; content: string }[]
|
||||
model_response: string
|
||||
corrected_response: string | null
|
||||
quality_score: number // 0.0 to 1.0
|
||||
failure_reason: string
|
||||
task_id: string
|
||||
task_type: string
|
||||
task_name: string
|
||||
model_id: string
|
||||
model_name: string
|
||||
node_id: string
|
||||
gpu_id: number
|
||||
tokens_per_sec: number
|
||||
}
|
||||
|
||||
export interface SftLastAction {
|
||||
type: 'correct' | 'discard' | 'flag'
|
||||
item: SftQueueItem
|
||||
}
|
||||
|
||||
export const useSftStore = defineStore('sft', () => {
|
||||
const queue = ref<SftQueueItem[]>([])
|
||||
const totalRemaining = ref(0)
|
||||
const lastAction = ref<SftLastAction | null>(null)
|
||||
|
||||
const current = computed(() => queue.value[0] ?? null)
|
||||
|
||||
function removeCurrentFromQueue() {
|
||||
queue.value.shift()
|
||||
}
|
||||
|
||||
function setLastAction(type: SftLastAction['type'], item: SftQueueItem) {
|
||||
lastAction.value = { type, item }
|
||||
}
|
||||
|
||||
function clearLastAction() {
|
||||
lastAction.value = null
|
||||
}
|
||||
|
||||
function restoreItem(item: SftQueueItem) {
|
||||
queue.value.unshift(item)
|
||||
}
|
||||
|
||||
return {
|
||||
queue, totalRemaining, lastAction, current,
|
||||
removeCurrentFromQueue, setLastAction, clearLastAction, restoreItem,
|
||||
}
|
||||
})
|
||||
Loading…
Reference in a new issue