Changeset 0.28.0.8 (#180)
This commit is contained in:
@@ -117,8 +117,14 @@ func (e *Extractor) Extract(ctx context.Context, channelID, userID, teamID, pers
|
||||
prompt := defaultExtractionPrompt
|
||||
if personaID != "" && e.stores.Personas != nil {
|
||||
persona, err := e.stores.Personas.GetByID(ctx, personaID)
|
||||
if err == nil && persona.MemoryExtractionPrompt != nil && *persona.MemoryExtractionPrompt != "" {
|
||||
prompt = *persona.MemoryExtractionPrompt
|
||||
if err == nil {
|
||||
// Respect persona memory_enabled flag (H6 — audit v0.28.0)
|
||||
if !persona.MemoryEnabled {
|
||||
return nil
|
||||
}
|
||||
if persona.MemoryExtractionPrompt != nil && *persona.MemoryExtractionPrompt != "" {
|
||||
prompt = *persona.MemoryExtractionPrompt
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -76,21 +76,23 @@ type candidate struct {
|
||||
ChannelID string
|
||||
UserID string
|
||||
TeamID string
|
||||
PersonaID string // non-empty if a persona is active on the channel
|
||||
}
|
||||
|
||||
func (s *Scanner) scan() {
|
||||
ctx := context.Background()
|
||||
|
||||
// Check global kill switch
|
||||
// Check global kill switch.
|
||||
// Default: ENABLED. Only disable if the key exists and is explicitly false.
|
||||
// This inverts the previous behavior where a missing key blocked all extraction.
|
||||
if s.stores.GlobalConfig != nil {
|
||||
val, err := s.stores.GlobalConfig.Get(ctx, "memory_extraction_enabled")
|
||||
if err != nil || val == nil {
|
||||
return // disabled or not configured
|
||||
}
|
||||
// val is a map; check the "value" key
|
||||
if enabled, ok := val["value"].(bool); !ok || !enabled {
|
||||
return
|
||||
if err == nil && val != nil {
|
||||
if enabled, ok := val["value"].(bool); ok && !enabled {
|
||||
return // explicitly disabled
|
||||
}
|
||||
}
|
||||
// If key is missing (err != nil or val == nil), extraction is enabled.
|
||||
}
|
||||
|
||||
candidates, err := s.findCandidates(ctx)
|
||||
@@ -124,7 +126,7 @@ func (s *Scanner) scan() {
|
||||
extractCtx, cancel := context.WithTimeout(ctx, 2*time.Minute)
|
||||
defer cancel()
|
||||
|
||||
if err := s.extractor.Extract(extractCtx, cand.ChannelID, cand.UserID, cand.TeamID, ""); err != nil {
|
||||
if err := s.extractor.Extract(extractCtx, cand.ChannelID, cand.UserID, cand.TeamID, cand.PersonaID); err != nil {
|
||||
log.Printf("⚠ memory extraction failed: channel=%s user=%s: %v",
|
||||
cand.ChannelID, cand.UserID, err)
|
||||
}
|
||||
@@ -135,6 +137,12 @@ func (s *Scanner) scan() {
|
||||
}
|
||||
|
||||
// findCandidates queries for channels with enough new activity since last extraction.
|
||||
//
|
||||
// Fixes from v0.28.0 audit:
|
||||
// - Uses channels.user_id (was: non-existent created_by)
|
||||
// - Uses channels.team_id directly (was: JOIN to non-existent channel_users table)
|
||||
// - JOINs channel_participants + personas to check memory_enabled (H6)
|
||||
// - Filters out channels whose active persona has memory_enabled=false
|
||||
func (s *Scanner) findCandidates(ctx context.Context) ([]candidate, error) {
|
||||
db := database.DB
|
||||
if db == nil {
|
||||
@@ -144,11 +152,17 @@ func (s *Scanner) findCandidates(ctx context.Context) ([]candidate, error) {
|
||||
var query string
|
||||
if database.IsSQLite() {
|
||||
query = `
|
||||
SELECT c.id, c.created_by, COALESCE(cu.team_id, '')
|
||||
SELECT c.id, c.user_id, COALESCE(c.team_id, ''),
|
||||
COALESCE(cp.participant_id, '')
|
||||
FROM channels c
|
||||
LEFT JOIN channel_users cu ON cu.channel_id = c.id AND cu.user_id = c.created_by
|
||||
LEFT JOIN memory_extraction_log mel ON mel.channel_id = c.id AND mel.user_id = c.created_by
|
||||
WHERE c.created_by IS NOT NULL
|
||||
LEFT JOIN channel_participants cp
|
||||
ON cp.channel_id = c.id AND cp.participant_type = 'persona'
|
||||
LEFT JOIN personas p
|
||||
ON p.id = cp.participant_id
|
||||
LEFT JOIN memory_extraction_log mel
|
||||
ON mel.channel_id = c.id AND mel.user_id = c.user_id
|
||||
WHERE c.user_id IS NOT NULL
|
||||
AND (cp.id IS NULL OR p.memory_enabled = 1)
|
||||
AND (
|
||||
SELECT COUNT(*) FROM messages m
|
||||
WHERE m.channel_id = c.id
|
||||
@@ -161,11 +175,17 @@ func (s *Scanner) findCandidates(ctx context.Context) ([]candidate, error) {
|
||||
`
|
||||
} else {
|
||||
query = `
|
||||
SELECT c.id, c.created_by, COALESCE(cu.team_id, '')
|
||||
SELECT c.id, c.user_id, COALESCE(c.team_id::text, ''),
|
||||
COALESCE(cp.participant_id::text, '')
|
||||
FROM channels c
|
||||
LEFT JOIN channel_users cu ON cu.channel_id = c.id AND cu.user_id = c.created_by
|
||||
LEFT JOIN memory_extraction_log mel ON mel.channel_id = c.id AND mel.user_id = c.created_by
|
||||
WHERE c.created_by IS NOT NULL
|
||||
LEFT JOIN channel_participants cp
|
||||
ON cp.channel_id = c.id AND cp.participant_type = 'persona'
|
||||
LEFT JOIN personas p
|
||||
ON p.id = cp.participant_id
|
||||
LEFT JOIN memory_extraction_log mel
|
||||
ON mel.channel_id = c.id AND mel.user_id = c.user_id
|
||||
WHERE c.user_id IS NOT NULL
|
||||
AND (cp.id IS NULL OR p.memory_enabled = true)
|
||||
AND (
|
||||
SELECT COUNT(*) FROM messages m
|
||||
WHERE m.channel_id = c.id
|
||||
@@ -187,7 +207,7 @@ func (s *Scanner) findCandidates(ctx context.Context) ([]candidate, error) {
|
||||
var candidates []candidate
|
||||
for rows.Next() {
|
||||
var c candidate
|
||||
if err := rows.Scan(&c.ChannelID, &c.UserID, &c.TeamID); err != nil {
|
||||
if err := rows.Scan(&c.ChannelID, &c.UserID, &c.TeamID, &c.PersonaID); err != nil {
|
||||
continue
|
||||
}
|
||||
candidates = append(candidates, c)
|
||||
|
||||
Reference in New Issue
Block a user