90 lines
3.3 KiB
Go
90 lines
3.3 KiB
Go
package elderagent
|
|||
|
|
|
||
|
|
import (
|
||
|
|
"bytes"
|
||
|
|
"context"
|
||
|
|
"encoding/json"
|
||
|
|
"fmt"
|
||
|
|
"strings"
|
||
|
|
|
||
|
|
"data-terminal-cloud/internal/memoryidentity"
|
||
|
|
)
|
||
|
|
|
||
|
|
// Native memory uses exactly the identity used by transcript uploads. Never
|
||
|
|
// inherit the template's shared user filter or use a device as the identity.
|
||
|
|
func (s *Service) nativeMemoryConfiguration(tenant, subject string, allowed bool) (map[string]any, error) {
|
||
|
|
if !allowed {
|
||
|
|
return map[string]any{"Enable": false}, nil
|
||
|
|
}
|
||
|
|
collection, event := strings.TrimSpace(s.VikingCollectionName), strings.TrimSpace(s.VikingEventType)
|
||
|
|
if collection == "" || event == "" || tenant == "" || subject == "" {
|
||
|
|
return nil, fmt.Errorf("VIKING_NATIVE_MEMORY_CONFIG_REQUIRED")
|
||
|
|
}
|
||
|
|
return map[string]any{"Enable": true, "Provider": "volc", "ProviderParams": map[string]any{
|
||
|
|
"collection_name": collection, "limit": 3,
|
||
|
|
"filter": map[string]any{"user_id": []string{memoryidentity.UserID(tenant, subject)}, "assistant_id": []string{memoryidentity.AssistantID}, "memory_type": []string{event}},
|
||
|
|
}}, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
// NativeMemoryConfiguration keeps saved-bot upgrades in the upload namespace.
|
||
|
|
func (s *Service) NativeMemoryConfiguration(tenant, subject string, allowed bool) (map[string]any, error) {
|
||
|
|
return s.nativeMemoryConfiguration(tenant, subject, allowed)
|
||
|
|
}
|
||
|
|
|
||
|
|
func (s *Service) configureNativeMemory(ctx context.Context, subject string, config map[string]any) error {
|
||
|
|
var tenant string
|
||
|
|
var allowed bool
|
||
|
|
err := s.Pool.QueryRow(ctx, `SELECT p.tenant_id::text,p.status='active' AND call_memory_authorized(p.id) AND COALESCE((SELECT effective_consents @> '{"voice_chat":true}'::jsonb FROM consent_snapshot WHERE subject_id=p.id ORDER BY snapshot_version DESC LIMIT 1),false) AND NOT EXISTS(SELECT 1 FROM privacy_request WHERE subject_id=p.id AND request_type='DELETE') FROM subject_profile p WHERE p.id=$1::uuid`, subject).Scan(&tenant, &allowed)
|
||
|
|
if err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
config["MemoryConfig"], err = s.nativeMemoryConfiguration(tenant, subject, allowed)
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
|
||
|
|
// Read back the filter too: checking Enable alone cannot detect cross-elder
|
||
|
|
// retrieval or an incorrect collection. Provider credentials are never read.
|
||
|
|
func (c *Client) VerifyNativeMemory(ctx context.Context, id string, expected map[string]any) error {
|
||
|
|
var result struct {
|
||
|
|
Bots []Bot `json:"Bots"`
|
||
|
|
}
|
||
|
|
if err := c.call(ctx, "AibotQuery", map[string]any{"Id": id}, &result); err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
for _, bot := range result.Bots {
|
||
|
|
if bot.ID != id {
|
||
|
|
continue
|
||
|
|
}
|
||
|
|
actual, _ := bot.Config["MemoryConfig"].(map[string]any)
|
||
|
|
rawEnabled, present := actual["Enable"]
|
||
|
|
enabled, valid := rawEnabled.(bool)
|
||
|
|
if present && !valid {
|
||
|
|
break
|
||
|
|
}
|
||
|
|
wantEnabled, _ := expected["Enable"].(bool)
|
||
|
|
if enabled != wantEnabled {
|
||
|
|
break
|
||
|
|
}
|
||
|
|
if !wantEnabled {
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
want, _ := json.Marshal(expected["ProviderParams"])
|
||
|
|
got, _ := json.Marshal(actual["ProviderParams"])
|
||
|
|
if actual["Provider"] == expected["Provider"] && bytes.Equal(want, got) {
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
break
|
||
|
|
}
|
||
|
|
return fmt.Errorf("VIKING_NATIVE_MEMORY_VERIFY_FAILED")
|
||
|
|
}
|
||
|
|
|
||
|
|
func (s *Service) verifyNativeMemory(ctx context.Context, bot string, config map[string]any) error {
|
||
|
|
if verifier, ok := s.Provider.(interface {
|
||
|
|
VerifyNativeMemory(context.Context, string, map[string]any) error
|
||
|
|
}); ok {
|
||
|
|
memory, _ := config["MemoryConfig"].(map[string]any)
|
||
|
|
return verifier.VerifyNativeMemory(ctx, bot, memory)
|
||
|
|
}
|
||
|
|
return nil
|
||
|
|
}
|