mirror of
https://github.com/NeuralNomadsAI/CodeNomad.git
synced 2026-10-21 05:06:37 +00:00
## Summary - Continue sparse history scans until a bounded result page is filled, publishing matches progressively across sessions. - Remove the automatic count traversal. Show page-local results and messages scanned directly from search responses, with no scan when opening an empty search. - Project text-only content in SQLite, reduce bounded RPC round trips, and share identical location checks only inside a request. ## Validation - UI/server typechecks and targeted server/store tests passed. - Chromium regression covers progressive results, pagination, workspace scope, technical toggle, empty results and absence of statistics requests. - Isolated native OpenCode 2.0.22 fixture passed, including all 242 workspace matches across two sessions and pruning/ownership regressions. - Synthetic benchmark: text search materializes 9.6 KB instead of 145 MB; CPU gain is modest because SQLite still parses stored JSON. See dev-docs/SESSION_HISTORY_QUERIES.md. ## Review Independent gatekeeper review and post-rebase validation in progress; findings will be addressed before administrator merge.
69 lines
4.3 KiB
JavaScript
69 lines
4.3 KiB
JavaScript
import assert from "node:assert/strict"
|
|
|
|
// Invoked only inside the pruning fixture's private daemon and synthetic DB.
|
|
export async function testSessionHistoryNative({ client, location, locationOptions, template }) {
|
|
const seed = await client.session.create({ title: "Isolated full-history fixture", location }, locationOptions)
|
|
const exported = await client.session.export({ sessionID: seed.id })
|
|
await client.session.remove({ sessionID: seed.id })
|
|
const messages = Array.from({ length: 241 }, (_, index) => ({
|
|
...structuredClone(template), id: `msg_history_fixture_${String(index).padStart(5, "0")}`,
|
|
content: [...template.content.map(part => part.type === "tool" ? { ...structuredClone(part), id: `history_call_${index}` } : structuredClone(part)),
|
|
{ type: "text", text: `Keep historicalneedle answer ${index}` }],
|
|
}))
|
|
const session = await client.session.import({ ...exported, messages, location }, locationOptions)
|
|
const rpc = async (method, input) => (await client.rpc.call({ rpcID: "codenomad.session-pruning", method, input, location }, locationOptions)).output
|
|
const scan = async (purpose, includeTechnical = true, sessionID = session.id) => {
|
|
let cursor, scanned = 0, tools = 0, reasoning = 0
|
|
const candidates = [], hits = []
|
|
do {
|
|
const page = await rpc("history", { ...(sessionID ? { sessionID } : {}), purpose, query: purpose === "search" ? "historicalneedle" : "", includeTechnical, ...(cursor ? { cursor } : {}) })
|
|
assert.equal(page.status, "page", JSON.stringify(page))
|
|
assert(page.scanned <= (purpose === "search" || (purpose === "stats" && !includeTechnical) ? 1024 : 32))
|
|
assert(page.hits.length <= 32 && page.sessions.length <= 32)
|
|
assert.equal(page.skipped, 0)
|
|
scanned += page.scanned; tools += page.tools; reasoning += page.reasoning
|
|
candidates.push(...page.candidates); hits.push(...page.hits)
|
|
cursor = page.cursor
|
|
} while (cursor)
|
|
return { scanned, tools, reasoning, candidates, hits }
|
|
}
|
|
try {
|
|
const before = await scan("stats")
|
|
assert.equal(before.scanned, 241)
|
|
assert.equal(before.tools, 241)
|
|
assert.equal(before.reasoning, 241)
|
|
assert.equal((await scan("search")).hits.length, 241)
|
|
const textOnly = await scan("search", false)
|
|
assert.equal(textOnly.hits.length, 241)
|
|
assert(textOnly.hits.every(hit => hit.kind === "text"))
|
|
const messagesOnly = await scan("stats", false)
|
|
assert.equal(messagesOnly.scanned, 241)
|
|
assert.equal(messagesOnly.tools + messagesOnly.reasoning, 0)
|
|
const peerSeed = await client.session.create({ title: "Isolated workspace history peer", location }, locationOptions)
|
|
const peerExport = await client.session.export({ sessionID: peerSeed.id })
|
|
await client.session.remove({ sessionID: peerSeed.id })
|
|
const peerMessage = { ...structuredClone(messages[0]), id: "msg_history_peer",
|
|
content: [{ type: "text", text: "Another historicalneedle answer in a different session" }] }
|
|
const peer = await client.session.import({ ...peerExport, messages: [peerMessage], location }, locationOptions)
|
|
try {
|
|
const workspace = await scan("search", false, null)
|
|
assert.equal(workspace.hits.length, 242)
|
|
assert.deepEqual(new Set(workspace.hits.map(hit => hit.sessionID)), new Set([session.id, peer.id]))
|
|
console.log("PASS: native text-only workspace search includes both sessions and all 242 matches")
|
|
} finally { await client.session.remove({ sessionID: peer.id }) }
|
|
const plan = await scan("prune")
|
|
assert.equal(plan.candidates.length, 241)
|
|
for (let offset = 0; offset < plan.candidates.length; offset += 16) {
|
|
const input = { sessionID: session.id, candidates: plan.candidates.slice(offset, offset + 16) }
|
|
const result = await rpc("pruneBatch", input)
|
|
assert(result.results.every(entry => entry.result.status === "pruned"), JSON.stringify(result))
|
|
assert.deepEqual(await rpc("pruneBatch", input), result, "batch receipts survive identical retries")
|
|
}
|
|
const after = await scan("stats")
|
|
assert.equal(after.scanned, 241)
|
|
assert.equal(after.tools, 0)
|
|
assert.equal(after.reasoning, 0)
|
|
assert.equal((await scan("search")).hits.length, 241, "answers remain searchable")
|
|
console.log("PASS: native 241-message counts, paginated search, complete technical cleanup and batch retry receipts")
|
|
} finally { await client.session.remove({ sessionID: session.id }) }
|
|
}
|