package vikingmemory import ( "context" "encoding/json" "errors" "strings" ) // Events are the managed unit: profiles are not independently regenerated from // a deleted/corrected event. Every event is mirrored into the editable platform // store before it can be used in a voice prompt. const ManagedAssistantID = "voicelink_managed_v1" func (c *Client) AddManagedSession(ctx context.Context, session, user string, messages []Message, at int64) error { if session == "" || user == "" || len(messages) == 0 || len(messages) > 1000 { return errors.New("invalid managed session") } return c.call(ctx, "/api/memory/session/add", map[string]any{ "session_id": session, "messages": messages, "store_file": false, "metadata": map[string]any{"default_user_id": user, "default_assistant_id": ManagedAssistantID, "time": at}, "extract_memory_type": []string{c.options.EventType}, }, nil) } func (c *Client) ManagedEvents(ctx context.Context, user, session string) ([]Item, error) { if user == "" || session == "" { return nil, errors.New("managed scope required") } var data struct { Items []Item `json:"result_list"` } err := c.call(ctx, "/api/memory/event/search", map[string]any{"filter": map[string]any{ "user_id": []string{user}, "assistant_id": []string{ManagedAssistantID}, "session_id": []string{session}, "memory_type": []string{c.options.EventType}, }, "limit": 1000}, &data) if err != nil { return nil, err } if len(data.Items) >= 1000 { return nil, errors.New("managed result limit reached") } out := []Item{} for _, item := range data.Items { if item.ID == "" || !contains(item.UserID, user) || !contains(item.AssistantID, ManagedAssistantID) || item.SessionID != session { continue } var summary string if json.Unmarshal(item.MemoryInfo["summary"], &summary) != nil { continue } summary = strings.TrimSpace(summary) if summary == "" || len([]rune(summary)) > 4000 { continue } item.Content = summary out = append(out, item) } return out, nil }