feat(gateway): admin 列表端点接真实数据——persona/session/memory 补 List() 并注入 gateway.Deps
CI / Backend (build / vet / test / cross-compile) (push) Has been cancelled
CI / Frontend (tsc + vite build) (push) Has been cancelled

根因:gateway.Server 定义 SessionStore/PersonaStore/MemoryStore 接口但生产从未满足:
- 底层 manager 无 List() 方法;
- wireFrontend 的 gateway.Deps{} 未传 Session/Personas/Memories。
→ /api/v1/sessions|personas 与 /api/v1/admin/{sessions,personas,memories} 恒返回 []。

改动:
- persona/registry:Registry.List() []Character(并发安全、值拷贝)。
- channel/session:SessionManager.List(ctx)(查 channel_sessions 表+按 actor_role 重建)。
- runtime/memory:Store.List(ctx)(全表,复用 scanItems)。
- gateway 三 Store 接口改为返回域类型(Character/MemoryItem),映射统一放 collect* 侧。
- cmd/cyrene/wire.go:Deps 补传 Session/Personas/Memories。
- .gitignore:cyrene→/cyrene(锚定根,不再误伤 cmd/cyrene 目录)。

实机验证:/api/v1/admin/personas 返回 {id:cyrene,name:昔涟,isDefault:true}。
This commit is contained in:
Aska committed 2026-09-06 14:05:34 +08:00
1 parent 5dae2b9741
commit 04bfa2c7a7
11 files changed
+312 -18

No files matched your search

+23 -2
View File
@@ -158,12 +158,33 @@ func (s *Server) handleListPersonas(w http.ResponseWriter, r *http.Request) {
// collectPersonas returns a non-nil persona slice from the configured store.
func (s *Server) collectPersonas() []PersonaSummary {
out := make([]PersonaSummary, 0)
if s.personas != nil {
out = append(out, s.personas.List()...)
if s.personas == nil {
return out
}
for _, c := range s.personas.List() {
id := c.PersonaID
if id == "" {
id = c.ID
}
out = append(out, PersonaSummary{
ID: id,
Name: c.Name,
Character: c.Name,
IsDefault: c.Default,
Mode: firstMode(c.Modes),
})
}
return out
}
// firstMode returns the first declared behavior mode, or "" when none are set.
func firstMode(modes []string) string {
if len(modes) == 0 {
return ""
}
return modes[0]
}
// summaryOfSession maps a session.Session to its wire shape.
func summaryOfSession(sess session.Session) SessionSummary {
return SessionSummary{