diff --git a/app/sft.py b/app/sft.py
index c5aabc7..97ae573 100644
--- a/app/sft.py
+++ b/app/sft.py
@@ -271,3 +271,39 @@ def get_stats() -> dict[str, object]:
"by_task_type": by_task_type,
"export_ready": export_ready,
}
+
+
+# ── GET /config ─────────────────────────────────────────────────────────────
+
+@router.get("/config")
+def get_sft_config() -> dict:
+ """Return the current SFT configuration (bench_results_dir)."""
+ f = _config_file()
+ if not f.exists():
+ return {"bench_results_dir": ""}
+ try:
+ raw = yaml.safe_load(f.read_text(encoding="utf-8")) or {}
+ except yaml.YAMLError:
+ return {"bench_results_dir": ""}
+ return raw.get("sft", {"bench_results_dir": ""})
+
+
+class SftConfigPayload(BaseModel):
+ bench_results_dir: str
+
+
+@router.post("/config")
+def post_sft_config(payload: SftConfigPayload) -> dict:
+ """Write the bench_results_dir setting to the config file."""
+ f = _config_file()
+ f.parent.mkdir(parents=True, exist_ok=True)
+ try:
+ raw = yaml.safe_load(f.read_text(encoding="utf-8")) if f.exists() else {}
+ raw = raw or {}
+ except yaml.YAMLError:
+ raw = {}
+ raw["sft"] = {"bench_results_dir": payload.bench_results_dir}
+ tmp = f.with_suffix(".tmp")
+ tmp.write_text(yaml.dump(raw, allow_unicode=True, sort_keys=False), encoding="utf-8")
+ tmp.rename(f)
+ return {"ok": True}
diff --git a/web/src/components/AppSidebar.vue b/web/src/components/AppSidebar.vue
index f691c9b..051feda 100644
--- a/web/src/components/AppSidebar.vue
+++ b/web/src/components/AppSidebar.vue
@@ -65,8 +65,9 @@ const navItems = [
{ path: '/', icon: '🃏', label: 'Label' },
{ path: '/fetch', icon: '📥', label: 'Fetch' },
{ path: '/stats', icon: '📊', label: 'Stats' },
- { path: '/benchmark', icon: '🏁', label: 'Benchmark' },
- { path: '/settings', icon: '⚙️', label: 'Settings' },
+ { path: '/benchmark', icon: '🏁', label: 'Benchmark' },
+ { path: '/corrections', icon: '✍️', label: 'Corrections' },
+ { path: '/settings', icon: '⚙️', label: 'Settings' },
]
const stowed = ref(localStorage.getItem(LS_KEY) === 'true')
diff --git a/web/src/router/index.ts b/web/src/router/index.ts
index 9e64197..24f9321 100644
--- a/web/src/router/index.ts
+++ b/web/src/router/index.ts
@@ -5,15 +5,17 @@ import LabelView from '../views/LabelView.vue'
const FetchView = () => import('../views/FetchView.vue')
const StatsView = () => import('../views/StatsView.vue')
const BenchmarkView = () => import('../views/BenchmarkView.vue')
-const SettingsView = () => import('../views/SettingsView.vue')
+const SettingsView = () => import('../views/SettingsView.vue')
+const CorrectionsView = () => import('../views/CorrectionsView.vue')
export const router = createRouter({
history: createWebHashHistory(),
routes: [
- { path: '/', component: LabelView, meta: { title: 'Label' } },
- { path: '/fetch', component: FetchView, meta: { title: 'Fetch' } },
- { path: '/stats', component: StatsView, meta: { title: 'Stats' } },
- { path: '/benchmark', component: BenchmarkView, meta: { title: 'Benchmark' } },
- { path: '/settings', component: SettingsView, meta: { title: 'Settings' } },
+ { path: '/', component: LabelView, meta: { title: 'Label' } },
+ { path: '/fetch', component: FetchView, meta: { title: 'Fetch' } },
+ { path: '/stats', component: StatsView, meta: { title: 'Stats' } },
+ { path: '/benchmark', component: BenchmarkView, meta: { title: 'Benchmark' } },
+ { path: '/corrections', component: CorrectionsView, meta: { title: 'Corrections' } },
+ { path: '/settings', component: SettingsView, meta: { title: 'Settings' } },
],
})
diff --git a/web/src/views/SettingsView.vue b/web/src/views/SettingsView.vue
index f09c924..bcfe7ac 100644
--- a/web/src/views/SettingsView.vue
+++ b/web/src/views/SettingsView.vue
@@ -110,6 +110,63 @@
+
+
+ Import SFT (supervised fine-tuning) candidates from cf-orch benchmark runs.
+ cf-orch Integration
+
+
+
+
+
+
+
+
+ Timestamp
+ Candidates
+ Imported
+
+
+
+
+ {{ run.timestamp }}
+ {{ run.candidate_count }}
+ {{ run.already_imported ? '✓' : '—' }}
+
+
+
+