P8 短板齊平:模型品質實測(granite 否決、qwen3-30b 定案)+額度撞牆三句話接上畫面
① docs/benchmarks/p8-extractor-quality/:leo 真筆記 8 篇 × 5 模型可複驗實測 (production 同 prompt/參數、CF 原生 usage.neurons 計量)—— scout 84 n/檔(119 檔/日)→ qwen3-30b 43 n/檔(232 檔/日)品質不降反升; granite 最便宜(858 檔/日)但 5/8 缺段、三元組全滅=否決。 誠實結論:免金鑰路物理撐不起「幾千篇當天匯入」(差 13 倍), 正解=消化節奏(3,000 篇約 13 天背景跑完、新筆記優先)+出口(Gemini/付費/ollama)。 ② 撞牆體驗:quota_message 08-07 就在 status.json,App 從來沒接—— app.go pickQuotaNotice(過期快照不說謊)+ main.js cardQuota(三句話卡)+ progress.go ClassifyFailure 補認三句話(原本掉「其他」)。 Go 兩 module 全綠;瀏覽器實載 dist 深淺兩主題截圖、console 0 錯。 ③ 公開鏡像排除 docs/benchmarks(輸入是 leo 私人筆記)。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -249,6 +249,15 @@ type UIState struct {
|
||||
EngineTrouble bool `json:"engineTrouble"`
|
||||
Progress UIProgress `json:"progress"` // 首頁「你的檔案」那行(t210)
|
||||
LogFolder string `json:"logFolder"`
|
||||
// Quota=「今天的 AI 額度用完了」那張卡(P8,2026-08-09)。
|
||||
//
|
||||
// 🔴 存在理由:collector 這半(quota.go)2026-08-07 就把 leo 定的三句話
|
||||
// (成就/出口/保證)寫進 status.json 的 quota_message 了,但 App 端從來沒接——
|
||||
// 使用者撞到額度時只看得到「送不上去 N 份」,正是封測者 Evan 把額度用完
|
||||
// 讀成「這個 AI 沒效」的那個黑箱(歸錯因、罵錯對象)。
|
||||
// 這裡原樣接住 collector 組好的三句話,不重新組字串(避免措辭漂移)。
|
||||
// nil=現在不在額度冷卻中,前端不畫這張卡。
|
||||
Quota *collector.QuotaNotice `json:"quota"`
|
||||
}
|
||||
|
||||
// UISkipped=首頁那張「這些檔案現在還處理不了」的卡。
|
||||
@@ -311,6 +320,36 @@ func buildProgress(s syncStatus) UIProgress {
|
||||
return u
|
||||
}
|
||||
|
||||
// pickQuotaNotice 從 status.json 的 per-account 狀態裡挑出「現在還有效」的額度三句話。
|
||||
//
|
||||
// 有效=ResumeAt 還沒到:collector 每輪重建 AccountSyncStatus,冷卻過了自然不再寫
|
||||
// quota_message,但 daemon 若整夜沒跑(電腦闔蓋),status.json 會停在昨天的快照——
|
||||
// 額度其實已經恢復了,這時再顯示「明天早上 8 點恢復」就是在說謊,所以以 ResumeAt 判生死。
|
||||
// 多帳號同時冷卻時挑最早恢復的那份(key 排序保證同一份輸入永遠同一個輸出,好測試)。
|
||||
func pickQuotaNotice(s syncStatus, now time.Time) *collector.QuotaNotice {
|
||||
keys := make([]string, 0, len(s.AccountDetails))
|
||||
for k := range s.AccountDetails {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
var best *collector.QuotaNotice
|
||||
var bestAt time.Time
|
||||
for _, k := range keys {
|
||||
q := s.AccountDetails[k].QuotaMessage
|
||||
if q == nil {
|
||||
continue
|
||||
}
|
||||
at, err := time.Parse(time.RFC3339, q.ResumeAt)
|
||||
if err != nil || !at.After(now) {
|
||||
continue // 解析不了或已恢復 ⇒ 過期快照,不畫(下一輪 collector 會清掉)
|
||||
}
|
||||
if best == nil || at.Before(bestAt) {
|
||||
best, bestAt = q, at
|
||||
}
|
||||
}
|
||||
return best
|
||||
}
|
||||
|
||||
// buildSkipped 把 status.json 的三個欄位翻成首頁看得懂的一張卡。
|
||||
// 完全沒有東西被略過時回 nil ⇒ 前端不畫這張卡(沒事就別佔畫面)。
|
||||
func buildSkipped(s syncStatus) *UISkipped {
|
||||
@@ -458,6 +497,7 @@ func (a *App) GetState() UIState {
|
||||
st.Steps = buildSteps(sync, st.Syncing)
|
||||
st.Skipped = buildSkipped(sync)
|
||||
st.Progress = buildProgress(sync)
|
||||
st.Quota = pickQuotaNotice(sync, time.Now()) // P8:額度冷卻中 ⇒ 首頁畫三句話卡
|
||||
// 引擎有問題才把「回報問題」卡叫出來(含記錄檔路徑)。
|
||||
// 沒事時不顯示——否則「哪裡看 log」會變成常駐噪音,真出事時反而沒人看。
|
||||
st.EngineTrouble = !collectorAlive()
|
||||
|
||||
Reference in New Issue
Block a user