my harness for niri
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 177 lines 6.1 kB view raw
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- 1499679672404021248 [mention] [channel/staying up till 1 billion oclock/#niri] [2026-05-01 03:11:14.553Z] @meowskullz: awa` 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("latestMemoryRecallQuery skips ambient discord batch without pending items", () => { 40 const batch = `[user/discord] [discord batch] 2026-05-01T03:10:50.162Z -> 2026-05-01T03:11:22.198Z 41new_messages=1 channels=1 pending_inbox=0 scope=configured+dm 42 43recent messages: 44- [channel/meowskullz's server/#ai-sister-yap] [2026-05-01 08:01:35.639Z] @rose: foxie emoji 45 46pending preview: 47- (none)` 48 49 const conversation: Message[] = [ 50 { role: "user", content: "what did we talk about when lisya was buying monero" }, 51 { role: "assistant", content: "..." }, 52 { role: "user", content: batch }, 53 ] 54 55 assert.equal( 56 __memoryTest.latestMemoryRecallQuery(conversation), 57 "what did we talk about when lisya was buying monero", 58 ) 59}) 60 61test("memoryQueryForUserMessage ignores ambient discord batch recent messages", () => { 62 const batch = `[user/discord] [discord batch] 2026-05-01T03:10:50.162Z -> 2026-05-01T03:11:22.198Z 63new_messages=1 channels=1 pending_inbox=0 scope=configured+dm 64 65recent messages: 66- [channel/meowskullz's server/#ai-sister-yap] [2026-05-01 08:01:35.639Z] @rose: foxie emoji 67 68pending preview: 69- (none)` 70 71 assert.deepEqual(__memoryTest.memoryQueryForUserMessage(batch), { 72 sender: null, 73 source: null, 74 body: batch, 75 }) 76}) 77 78test("memoryQueryForUserMessage parses discord DM envelope into parts", () => { 79 const dm = `[discord/dm] @meowskullz 80context: DM 1234567890 81message_id: 9999 82timestamp: 2026-05-01T00:00:00Z 83action: This is a direct message. Reply if it needs a response. 84 85thanks` 86 87 const parts = __memoryTest.memoryQueryForUserMessage(dm) 88 assert.equal(parts.sender, "meowskullz") 89 assert.equal(parts.source, "DM") 90 assert.equal(parts.body, "thanks") 91}) 92 93test("buildSearchProfile uses sender as primary signal and drops source", async () => { 94 const profile = await __memoryTest.buildSearchProfile({ 95 sender: "meowskullz", 96 source: "DM", 97 body: "thanks", 98 }) 99 100 assert.equal(profile.sender, "meowskullz") 101 assert.equal(profile.personQuery, true) 102 assert.deepEqual(profile.bodyTokens, ["thanks"]) 103 assert.ok(profile.tokens.includes("meowskullz")) 104 assert.ok(profile.tokens.includes("thanks")) 105 assert.ok(!profile.tokens.includes("dm"), "source label should not become a search token") 106}) 107 108test("resolveAliases follows transitive mappings without cycles", () => { 109 const map = { 110 meowskullz: ["ana"], 111 ana: ["ana_canonical"], 112 foo: ["meowskullz"], 113 } 114 assert.deepEqual(__memoryTest.resolveAliases("meowskullz", map), ["ana", "ana_canonical"]) 115 assert.deepEqual(__memoryTest.resolveAliases("foo", map), ["meowskullz", "ana", "ana_canonical"]) 116 assert.deepEqual(__memoryTest.resolveAliases(null, map), []) 117}) 118 119test("buildSearchProfile expands sender via alias map", async (t) => { 120 const fs = await import("node:fs/promises") 121 const path = await import("node:path") 122 const url = await import("node:url") 123 const memoriesDir = path.resolve(url.fileURLToPath(import.meta.url), "../../home/memories") 124 const aliasFile = path.join(memoriesDir, "aliases.json") 125 const had = await fs.readFile(aliasFile, "utf-8").catch(() => null) 126 127 await fs.mkdir(memoriesDir, { recursive: true }) 128 await fs.writeFile(aliasFile, JSON.stringify({ meowskullz: ["ana"] }), "utf-8") 129 130 t.after(async () => { 131 if (had !== null) await fs.writeFile(aliasFile, had, "utf-8") 132 else await fs.rm(aliasFile, { force: true }) 133 }) 134 135 const profile = await __memoryTest.buildSearchProfile({ 136 sender: "meowskullz", 137 source: "DM", 138 body: "thanks", 139 }) 140 141 assert.deepEqual(profile.senderAliases, ["ana"]) 142 assert.ok(profile.tokens.includes("ana")) 143}) 144 145test("buildSearchProfile body informativeness short-circuits on body-people", async () => { 146 const withPerson = await __memoryTest.buildSearchProfile({ 147 sender: "meowskullz", 148 source: "DM", 149 body: "yayy, who is rea", 150 }) 151 assert.equal(withPerson.bodyInformative, true) 152 153 const empty = await __memoryTest.buildSearchProfile({ sender: "meowskullz", source: "DM", body: "" }) 154 assert.equal(empty.bodyInformative, false) 155}) 156 157test("buildSearchProfile detects people mentioned in body", async () => { 158 const profile = await __memoryTest.buildSearchProfile({ 159 sender: "meowskullz", 160 source: "DM", 161 body: "patpat, who is rea", 162 }) 163 164 assert.ok(profile.bodyPeople.includes("rea"), `expected rea in bodyPeople, got ${JSON.stringify(profile.bodyPeople)}`) 165 assert.ok(profile.tokens.includes("rea")) 166 assert.equal(profile.personQuery, true) 167}) 168 169test("searchTokens keeps meaningful body terms", () => { 170 assert.deepEqual(__memoryTest.searchTokens("staying up till 1 billion oclock awa"), [ 171 "staying", 172 "till", 173 "billion", 174 "oclock", 175 "awa", 176 ]) 177})