chore: retire the tag-eval harness — it proved the heads system, job done (operator-approved)
The head-vs-centroid eval (#1130) existed to prove the 'frozen embedding + trained head' spine; the operator accepted the tagging system and dropped the harness. Removed per rule 22: TagEvalCard + store, /api/tag_eval blueprint, tag_eval_run ml task, recover-stalled-tag-eval-runs sweep + beat entry, TagEvalRun model + table (migration 0073), and its tests. The eval's data loaders + metric helpers were NOT eval-specific — the nightly heads trainer runs on them — so they moved verbatim to services/ml/training_data.py (heads.py import updated; behavior unchanged). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CDgx8bQS5YrGRK76v8HUnM
This commit is contained in:
@@ -1,57 +0,0 @@
|
||||
import { defineStore } from 'pinia'
|
||||
|
||||
import { useApi } from '../composables/useApi.js'
|
||||
|
||||
// Tag-eval (#1130): trigger + revisit the head-vs-centroid learning-curve eval.
|
||||
// The run + full report live server-side (tag_eval_run), so the card rehydrates
|
||||
// from getRun() on mount — the report survives navigation.
|
||||
export const useTagEvalStore = defineStore('tagEval', () => {
|
||||
const api = useApi()
|
||||
|
||||
async function start(params) {
|
||||
return await api.post('/api/tag-eval', { body: { params } })
|
||||
}
|
||||
|
||||
async function getRun(id) {
|
||||
return await api.get(`/api/tag-eval/${id}`) // includes the full report
|
||||
}
|
||||
|
||||
// The most recent run (light row, no report) — the card calls getRun() with
|
||||
// its id to pull the persisted report on mount.
|
||||
async function latest() {
|
||||
const body = await api.get('/api/tag-eval', { params: { limit: 1 } })
|
||||
return (body.runs && body.runs[0]) || null
|
||||
}
|
||||
|
||||
// --- Acting on the head's example lists (closes the learn-from-tags loop).
|
||||
// These write the SAME tables the head trains on: image_tag (positives) and
|
||||
// tag_suggestion_rejection (negatives, via the dismiss endpoint).
|
||||
|
||||
// "Yes, it is this" — apply the tag (new positive).
|
||||
async function applyTag(imageId, tagId) {
|
||||
return await api.post(`/api/images/${imageId}/tags`,
|
||||
{ body: { tag_id: tagId, source: 'manual' } })
|
||||
}
|
||||
|
||||
// "No, it's not" on an UNtagged suggestion — record a rejection (hard negative).
|
||||
async function rejectTag(imageId, tagId) {
|
||||
return await api.post(`/api/images/${imageId}/suggestions/dismiss`,
|
||||
{ body: { tag_id: tagId } })
|
||||
}
|
||||
|
||||
// "Not it" on one of YOUR positives the head doubts — remove the tag AND
|
||||
// record the rejection (kills the bad positive, leaves a hard negative).
|
||||
async function removeTag(imageId, tagId) {
|
||||
await api.delete(`/api/images/${imageId}/tags/${tagId}`)
|
||||
return await api.post(`/api/images/${imageId}/suggestions/dismiss`,
|
||||
{ body: { tag_id: tagId } })
|
||||
}
|
||||
|
||||
// "Keep" — affirm a doubted positive is correct. Records a confirmation so it
|
||||
// stops resurfacing in the doubts list (it stays a positive either way).
|
||||
async function confirmTag(imageId, tagId) {
|
||||
return await api.post(`/api/images/${imageId}/tags/${tagId}/confirm`)
|
||||
}
|
||||
|
||||
return { start, getRun, latest, applyTag, rejectTag, removeTag, confirmTag }
|
||||
})
|
||||
Reference in New Issue
Block a user