my harness for niri
1
fork

Configure Feed

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

at main 145 lines 4.1 kB view raw
1import assert from "node:assert/strict" 2import test from "node:test" 3import { __loopTest } from "./loop.js" 4import type { Message } from "../types.js" 5import type { LoopState } from "./types.js" 6import type { Message } from "../types.js" 7 8function makeState(): LoopState { 9 return { 10 conversation: [], 11 pendingInputs: [], 12 tokenCount: 0, 13 contextSize: 0, 14 toolInFlight: false, 15 memoryRecallCooldowns: {}, 16 memoryRecallTurn: 0, 17 } 18} 19 20test("applyDiscordSendNudge appends a follow-up user nudge for unsent Discord replies", () => { 21 const state = makeState() 22 const turnMessages: Message[] = [ 23 { 24 role: "user", 25 content: "[user/discord] [discord/dm] hey are you there", 26 }, 27 { 28 role: "assistant", 29 content: "yeah, i'm here", 30 }, 31 ] 32 33 const nudged = __loopTest.applyDiscordSendNudge(state, turnMessages) 34 35 assert.equal(nudged, true) 36 assert.equal(state.conversation.length, 1) 37 assert.match(String(state.conversation[0]?.content), /did not call discord_send/i) 38}) 39 40test("applyDiscordSendNudge fires after a harness restart when the discord event is pre-turn context", () => { 41 const state = makeState() 42 state.conversation.push( 43 { 44 role: "user", 45 content: "[harness restarted — discord @ 2026-05-01T04:30:00.000Z]\n\n[discord/dm] hi starfish", 46 }, 47 { 48 role: "assistant", 49 content: "i keep getting bounced by harness restarts sorry ^^ still here though! what's up?", 50 }, 51 ) 52 53 const turnStart = 1 54 const turnMessages: Message[] = [state.conversation[1]!] 55 56 const nudged = __loopTest.applyDiscordSendNudge(state, turnMessages, turnStart) 57 58 assert.equal(nudged, true) 59 assert.equal(state.conversation.length, 3) 60 assert.match(String(state.conversation[2]?.content), /did not call discord_send/i) 61}) 62 63test("applyDiscordSendNudge does not fire when discord_send was already called", () => { 64 const state = makeState() 65 const turnMessages: Message[] = [ 66 { 67 role: "user", 68 content: "[user/discord] [discord/channel] can you reply", 69 }, 70 { 71 role: "assistant", 72 content: "sending now", 73 tool_calls: [ 74 { 75 id: "call_123", 76 type: "function", 77 function: { 78 name: "discord_send", 79 arguments: "{\"channel_id\":\"1\",\"content\":\"sending now\"}", 80 }, 81 }, 82 ], 83 }, 84 ] 85 86 const nudged = __loopTest.applyDiscordSendNudge(state, turnMessages) 87 88 assert.equal(nudged, false) 89 assert.equal(state.conversation.length, 0) 90}) 91 92test("applyLoopGuardNudge appends an in-band user nudge and saves", async () => { 93 const state = makeState() 94 let saved = false 95 96 await __loopTest.applyLoopGuardNudge( 97 state, 98 { 99 waitForEvent: async () => { 100 throw new Error("unexpected wait") 101 }, 102 waitForEventWithTimeout: async () => null, 103 injectIncomingEvent: () => {}, 104 flushDeferredEvents: () => {}, 105 clearSession: async () => {}, 106 saveSession: async () => { 107 saved = true 108 }, 109 }, 110 "loop guard tripped after 120 turns", 111 ) 112 113 assert.equal(saved, true) 114 assert.equal(state.conversation.length, 1) 115 assert.equal(state.conversation[0]?.role, "user") 116 assert.match(String(state.conversation[0]?.content), /loop guard tripped after 120 turns/i) 117}) 118 119test("waitForNextEvent waits for and injects the next external event", async () => { 120 const calls: string[] = [] 121 const event = { 122 source: "chat" as const, 123 triggeredAt: "2026-05-01T04:40:00.000Z", 124 content: "still here", 125 raw: {}, 126 } 127 128 await __loopTest.waitForNextEvent(42, { 129 waitForEvent: async () => { 130 calls.push("wait") 131 return event 132 }, 133 waitForEventWithTimeout: async () => null, 134 injectIncomingEvent: (_convId, incoming) => { 135 calls.push(`inject:${incoming.content}`) 136 assert.equal(_convId, 42) 137 assert.equal(incoming, event) 138 }, 139 flushDeferredEvents: () => {}, 140 clearSession: async () => {}, 141 saveSession: async () => {}, 142 }) 143 144 assert.deepEqual(calls, ["wait", "inject:still here"]) 145})