Files
story/internal/vikingmemory/console.go
T
Codex Local bf1233d5df
ci / verify (push) Canceled after 0s
feat: expand companion platform, device controls, and memoir workflows
Add customer and operator login, BLE provisioning, device fleet controls, call memory, memoir generation, and refreshed family and maintenance portals. Include API contracts, migrations, firmware sources, tests, assets, and deployment documentation.
2026-10-08 10:06:44 +08:00

86 lines
2.8 KiB
Go

package vikingmemory
import (
"context"
"crypto/sha256"
"data-terminal-cloud/internal/callmemory"
"encoding/hex"
"encoding/json"
"errors"
"strings"
)
// ChatMemories returns untruncated native-chat records and checks scope again on
// every provider result. Memoir extraction and projection assistants are excluded.
func (c *Client) ChatMemories(ctx context.Context, user, kind, query string, limit int, start, end int64) ([]callmemory.VikingRecord, bool, error) {
if user == "" || kind != "event" && kind != "profile" || limit < 1 || limit > 5000 {
return nil, false, errors.New("invalid chat memory scope")
}
rule := c.options.EventType
if kind == "profile" {
rule = c.options.ProfileType
}
filter := map[string]any{"user_id": []string{user}, "assistant_id": []string{AssistantID}, "memory_type": []string{rule}}
if start > 0 {
filter["start_time"] = start
}
if end > 0 {
filter["end_time"] = end
}
payload := map[string]any{"filter": filter, "limit": limit}
if query != "" {
payload["query"] = query
}
var data struct {
Items []struct {
Item
Time int64 `json:"time"`
Types []string `json:"memory_type"`
} `json:"result_list"`
}
if e := c.call(ctx, "/api/memory/"+kind+"/search", payload, &data); e != nil {
return nil, false, e
}
out := []callmemory.VikingRecord{}
limited := len(data.Items) >= limit
for _, item := range data.Items {
// Shared records cannot be deleted through an individual elder's console.
if item.ID == "" || len(item.UserID) != 1 || item.UserID[0] != user || len(item.AssistantID) != 1 || item.AssistantID[0] != AssistantID || !contains(item.Types, rule) {
// A filtered or malformed response cannot prove a deleted ID is absent.
limited = true
continue
}
content := []string{}
for _, key := range []string{"summary", "user_profile"} {
if raw := item.MemoryInfo[key]; len(raw) > 0 {
var text string
if json.Unmarshal(raw, &text) != nil {
text = string(raw)
}
if strings.TrimSpace(text) != "" {
content = append(content, text)
}
}
}
if len(content) == 0 {
b, _ := json.MarshalIndent(item.MemoryInfo, "", " ")
content = append(content, string(b))
}
r := callmemory.VikingRecord{ID: item.ID, Kind: kind, Time: item.Time, SessionID: item.SessionID, Content: strings.Join(content, "\n"), MemoryInfo: item.MemoryInfo}
raw, e := json.Marshal(r)
if e != nil {
return nil, false, e
}
sum := sha256.Sum256(raw)
r.Digest = hex.EncodeToString(sum[:])
out = append(out, r)
}
return out, limited, nil
}
func (c *Client) DeleteChatMemory(ctx context.Context, kind, id string) error {
if (kind != "event" && kind != "profile") || id == "" {
return errors.New("invalid chat memory deletion")
}
return c.call(ctx, "/api/memory/"+kind+"/delete", map[string]any{kind + "_id": id}, nil)
}