feat(t52): per-folder 庫章——DirectConfig.libraries 對映+libraryFor()(資料夾名 slug/中文退後備/明列優先,go test 綠);兩支 ingest workflow 的 post_block metadata 補 library(真兇:blocks 沒蓋章=兩資料夾全歸 general);托盤連線時回報庫自動登記

This commit is contained in:
2026-07-26 01:53:44 +08:00
parent 3675f38e59
commit fedb765742
3 changed files with 151 additions and 3 deletions
+48 -3
View File
@@ -43,7 +43,11 @@ type DirectConfig struct {
APIKey string `json:"api_key"` // X-Arcrun-API-Key(空=沿用 namespacedemo 慣例)
Email string `json:"email,omitempty"` // 實例主身分(t26;人人記得自己的 email,CF 全程隱形)
InstanceName string `json:"instance_name,omitempty"` // 暱稱(t26 選配;不取就顯示 email)
Library string `json:"library"` // 藏書地圖歸庫鍵(空=kb
Library string `json:"library"` // 藏書地圖歸庫鍵(空=kbper-folder 未指定時的後備
// t52leo 2026-07-25 裁決:「資料夾=庫」——企業有 10 個資料夾,財務/人事不准任何人看,
// 全塞一個庫=找死):每個看守資料夾對應自己的庫。key=資料夾絕對路徑,value=庫名。
// 未列出的資料夾=用資料夾名 slug 當庫名(librarySlug);再不行才退回 Library。
Libraries map[string]string `json:"libraries,omitempty"`
IngestWF string `json:"ingest_workflow"` // 直送萃取 workflow 名(空=rag_ingest_directextractor 模式不用)
RemovedWF string `json:"removed_workflow"` // 下架 workflow 名(空=rag_takedown_direct;吃 {page_name,path}
// —— 四步定稿(daemon-beta t3/t4/t6):本地萃卡模式 ——
@@ -56,6 +60,47 @@ type DirectConfig struct {
MaxRemoved float64 `json:"max_removed_ratio"` // 大量刪除防呆門檻(空/0=0.4)
}
// librarySlug 把資料夾名轉成合法庫名(A-Za-z0-9_-;中文等非 ASCII 轉為底線分段)。
// 空結果(如純中文名)回 "",交由 libraryFor 退回後備值——不硬造出無意義的庫名。
func librarySlug(folder string) string {
base := filepath.Base(strings.TrimRight(folder, string(filepath.Separator)))
var b strings.Builder
lastUnderscore := false
for _, r := range base {
switch {
case (r >= 'a' && r <= 'z') || (r >= '0' && r <= '9') || r == '-' || r == '_':
b.WriteRune(r)
lastUnderscore = false
case r >= 'A' && r <= 'Z':
b.WriteRune(r + 32) // 統一小寫(庫名大小寫不敏感比對較不易出錯)
lastUnderscore = false
default:
if !lastUnderscore && b.Len() > 0 {
b.WriteRune('_')
lastUnderscore = true
}
}
}
return strings.Trim(b.String(), "_")
}
// libraryFor 決定某個看守資料夾的資料該蓋哪個庫章(t52)。
// 優先序:config.Libraries 明列 > 資料夾名 slug > config.Library(後備,預設 kb)。
func (c *DirectConfig) libraryFor(absRoot string) string {
if c.Libraries != nil {
if lib, ok := c.Libraries[absRoot]; ok && strings.TrimSpace(lib) != "" {
return strings.TrimSpace(lib)
}
}
if slug := librarySlug(absRoot); slug != "" {
return slug
}
if c.Library != "" {
return c.Library
}
return "kb"
}
// expandHome 把開頭的 `~/`(或單獨的 `~`)展開成使用者家目錄的絕對路徑。
//
// t39(07-24 安裝器實案):成功頁下載的 config.json 把 manifest 寫成 `~/.arcrun-rag/manifest.json`——
@@ -327,7 +372,7 @@ func runDirectOnceRoot(cfg *DirectConfig, root string, dryRun bool) ([]DirectRes
"page_name": pageNameOf(cardRel),
"path": ev.Path,
"card_content": string(cardData),
"library": cfg.Library,
"library": cfg.libraryFor(absRoot),
})
res.HTTPStatus = status
if perr != nil {
@@ -349,7 +394,7 @@ func runDirectOnceRoot(cfg *DirectConfig, root string, dryRun bool) ([]DirectRes
"page_name": pageNameOf(ev.Path),
"path": ev.Path,
"content": string(content),
"library": cfg.Library,
"library": cfg.libraryFor(absRoot),
})
res.HTTPStatus = status
if perr != nil {