feat(t52): per-folder 庫章——DirectConfig.libraries 對映+libraryFor()(資料夾名 slug/中文退後備/明列優先,go test 綠);兩支 ingest workflow 的 post_block metadata 補 library(真兇:blocks 沒蓋章=兩資料夾全歸 general);托盤連線時回報庫自動登記
This commit is contained in:
@@ -43,7 +43,11 @@ type DirectConfig struct {
|
||||
APIKey string `json:"api_key"` // X-Arcrun-API-Key(空=沿用 namespace,demo 慣例)
|
||||
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"` // 藏書地圖歸庫鍵(空=kb;per-folder 未指定時的後備)
|
||||
// t52(leo 2026-07-25 裁決:「資料夾=庫」——企業有 10 個資料夾,財務/人事不准任何人看,
|
||||
// 全塞一個庫=找死):每個看守資料夾對應自己的庫。key=資料夾絕對路徑,value=庫名。
|
||||
// 未列出的資料夾=用資料夾名 slug 當庫名(librarySlug);再不行才退回 Library。
|
||||
Libraries map[string]string `json:"libraries,omitempty"`
|
||||
IngestWF string `json:"ingest_workflow"` // 直送萃取 workflow 名(空=rag_ingest_direct;extractor 模式不用)
|
||||
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 {
|
||||
|
||||
Reference in New Issue
Block a user