This repository has no description
1import test from "node:test"
2import assert from "node:assert/strict"
3import type { Message } from "./types.js"
4import { __memoryTest } from "./memory.js"
5
6test("latestMemoryRecallQuery falls back past scheduled heartbeat", () => {
7 const conversation: Message[] = [
8 { role: "user", content: "what did we talk about when lisya was buying monero" },
9 { role: "assistant", content: "..." },
10 { role: "user", content: "Scheduled heartbeat." },
11 ]
12
13 assert.equal(
14 __memoryTest.latestMemoryRecallQuery(conversation),
15 "what did we talk about when lisya was buying monero",
16 )
17})
18
19test("memoryQueryForUserMessage extracts structured parts from discord batch", () => {
20 const batch = `[user/discord] [discord batch] 2026-05-01T03:10:50.162Z -> 2026-05-01T03:11:22.198Z
21new_messages=1 channels=1 pending_inbox=0 scope=configured+dm
22auto_seen_timeout=10m auto_demoted=0
23channel_flag_repairs=0
24channel messages are context, not direct requests. replying is optional; use judgment.
25
26recent messages:
27- [channel/staying up till 1 billion oclock/#niri] [2026-05-01 03:11:14.553Z] @meowskullz: awa
28
29pending preview:
30- (none)`
31
32 assert.deepEqual(__memoryTest.memoryQueryForUserMessage(batch), {
33 sender: "meowskullz",
34 source: "channel/staying up till 1 billion oclock/#niri",
35 body: "awa",
36 })
37})
38
39test("memoryQueryForUserMessage parses discord DM envelope into parts", () => {
40 const dm = `[discord/dm] @meowskullz
41context: DM 1234567890
42message_id: 9999
43timestamp: 2026-05-01T00:00:00Z
44action: This is a direct message. Reply if it needs a response.
45
46thanks`
47
48 const parts = __memoryTest.memoryQueryForUserMessage(dm)
49 assert.equal(parts.sender, "meowskullz")
50 assert.equal(parts.source, "DM")
51 assert.equal(parts.body, "thanks")
52})
53
54test("buildSearchProfile uses sender as primary signal and drops source", async () => {
55 const profile = await __memoryTest.buildSearchProfile({
56 sender: "meowskullz",
57 source: "DM",
58 body: "thanks",
59 })
60
61 assert.equal(profile.sender, "meowskullz")
62 assert.equal(profile.personQuery, true)
63 assert.deepEqual(profile.bodyTokens, ["thanks"])
64 assert.ok(profile.tokens.includes("meowskullz"))
65 assert.ok(profile.tokens.includes("thanks"))
66 assert.ok(!profile.tokens.includes("dm"), "source label should not become a search token")
67})
68
69test("resolveAliases follows transitive mappings without cycles", () => {
70 const map = {
71 meowskullz: ["ana"],
72 ana: ["ana_canonical"],
73 foo: ["meowskullz"],
74 }
75 assert.deepEqual(__memoryTest.resolveAliases("meowskullz", map), ["ana", "ana_canonical"])
76 assert.deepEqual(__memoryTest.resolveAliases("foo", map), ["meowskullz", "ana", "ana_canonical"])
77 assert.deepEqual(__memoryTest.resolveAliases(null, map), [])
78})
79
80test("buildSearchProfile expands sender via alias map", async (t) => {
81 const fs = await import("node:fs/promises")
82 const path = await import("node:path")
83 const url = await import("node:url")
84 const memoriesDir = path.resolve(url.fileURLToPath(import.meta.url), "../../home/memories")
85 const aliasFile = path.join(memoriesDir, "aliases.json")
86 const had = await fs.readFile(aliasFile, "utf-8").catch(() => null)
87
88 await fs.mkdir(memoriesDir, { recursive: true })
89 await fs.writeFile(aliasFile, JSON.stringify({ meowskullz: ["ana"] }), "utf-8")
90
91 t.after(async () => {
92 if (had !== null) await fs.writeFile(aliasFile, had, "utf-8")
93 else await fs.rm(aliasFile, { force: true })
94 })
95
96 const profile = await __memoryTest.buildSearchProfile({
97 sender: "meowskullz",
98 source: "DM",
99 body: "thanks",
100 })
101
102 assert.deepEqual(profile.senderAliases, ["ana"])
103 assert.ok(profile.tokens.includes("ana"))
104})
105
106test("buildSearchProfile detects people mentioned in body", async () => {
107 const profile = await __memoryTest.buildSearchProfile({
108 sender: "meowskullz",
109 source: "DM",
110 body: "patpat, who is rea",
111 })
112
113 assert.ok(profile.bodyPeople.includes("rea"), `expected rea in bodyPeople, got ${JSON.stringify(profile.bodyPeople)}`)
114 assert.ok(profile.tokens.includes("rea"))
115 assert.equal(profile.personQuery, true)
116})
117
118test("searchTokens keeps meaningful body terms", () => {
119 assert.deepEqual(__memoryTest.searchTokens("staying up till 1 billion oclock awa"), [
120 "staying",
121 "till",
122 "billion",
123 "oclock",
124 "awa",
125 ])
126})