This commit is contained in:
NotExpectedYet committed 2026-09-26 05:35:29 +01:00
commit 0964819cdc
34 files changed
+7912

No files matched your search

+120
View File
@@ -0,0 +1,120 @@
import { strict as assert } from 'node:assert'
import { test } from 'node:test'
import { cleanVariant, createExpander, parseVariants } from '../lib/expand.js'
/** A stub endpoint that answers with a canned model response. */
function stubFetch(response, options = {}) {
const { status = 200, hang = false } = options
const calls = []
const impl = async (url, init) => {
calls.push({ url, body: JSON.parse(init.body) })
if (hang) {
return new Promise((_resolve, reject) => {
init.signal.addEventListener('abort', () => reject(init.signal.reason), { once: true })
})
}
return { ok: status === 200, status, json: async () => ({ response }) }
}
impl.calls = calls
return impl
}
const MODEL = { apiBase: 'http://stub:11434', model: 'small-model', timeoutMs: 2_000, count: 4 }
test('cleanVariant strips what models add around a list', () => {
assert.equal(cleanVariant('1. occupancy state machine'), 'occupancy state machine')
assert.equal(cleanVariant('- presence detection'), 'presence detection')
assert.equal(cleanVariant('* room occupied handler'), 'room occupied handler')
assert.equal(cleanVariant('"roomOccupied"'), 'roomOccupied')
assert.equal(cleanVariant('occupancy check — this finds the handler'), 'occupancy check')
assert.equal(cleanVariant(' '), undefined)
assert.equal(cleanVariant('x'.repeat(300)), undefined, 'a paragraph is not a search phrase')
assert.equal(cleanVariant('Here are some phrasings:'), undefined)
})
test('model commentary is never mistaken for a phrasing', () => {
// A line like this is not a weak variant, it is not a variant at all:
// embedding it would search the codebase for the model's apology.
for (const line of ['I cannot help with that.', "I can't do that.", 'Sorry, I need more context.', 'Unfortunately I do not have enough information.', 'Here are some phrasings:']) {
assert.equal(cleanVariant(line), undefined, `accepted ${line}`)
}
// But a question-shaped phrasing is entirely legitimate, and must survive.
assert.equal(cleanVariant('how does a room decide it is occupied'), 'how does a room decide it is occupied')
assert.equal(cleanVariant('where is the occupancy handler'), 'where is the occupancy handler')
})
test('parseVariants dedupes, drops the original, and caps the count', () => {
const body = ['occupancy state machine', 'room occupied detection', 'OCCUPANCY STATE MACHINE', 'presence tracking', 'extra one', 'extra two'].join('\n')
const variants = parseVariants(body, 'how does a room decide it is occupied', 3)
assert.deepEqual(variants, ['occupancy state machine', 'room occupied detection', 'presence tracking'])
})
test('expansion returns the original first, then the variants', async () => {
const fetchImpl = stubFetch('occupancy state machine\nroom occupied handler')
const variants = await createExpander({ ...MODEL, fetchImpl }).expand('how does a room decide it is occupied')
assert.equal(variants[0], 'how does a room decide it is occupied')
assert.deepEqual(variants.slice(1), ['occupancy state machine', 'room occupied handler'])
// The query must actually reach the model.
assert.match(fetchImpl.calls[0].body.prompt, /how does a room decide it is occupied/)
assert.equal(fetchImpl.calls[0].body.stream, false)
})
test('an unreachable endpoint degrades to the original query, never an error', async () => {
const fetchImpl = async () => {
throw new Error('ECONNREFUSED')
}
const variants = await createExpander({ ...MODEL, fetchImpl }).expand('some query')
assert.deepEqual(variants, ['some query'])
})
test('a WEDGED endpoint degrades to the original query, and does not hang', async () => {
// The failure actually observed on the box: the socket opens and nothing ever
// comes back. Expansion must give up on its own deadline rather than pass the
// wait on to a search that has nothing to do with the local model.
const fetchImpl = stubFetch('', { hang: true })
const started = Date.now()
const variants = await createExpander({ ...MODEL, fetchImpl, timeoutMs: 120 }).expand('some query')
assert.deepEqual(variants, ['some query'])
assert.ok(Date.now() - started < 3_000, 'the internal deadline must bound the wait')
})
test('a non-200 response degrades rather than throwing', async () => {
const variants = await createExpander({ ...MODEL, fetchImpl: stubFetch('', { status: 500 }) }).expand('q')
assert.deepEqual(variants, ['q'])
})
test('a response with nothing usable leaves just the original', async () => {
const variants = await createExpander({ ...MODEL, fetchImpl: stubFetch('I cannot help with that.') }).expand('q')
assert.deepEqual(variants, ['q'])
})
test('a non-finite timeout is clamped, not turned into a silent fallback', async () => {
// Without the clamp, AbortSignal.timeout(NaN) throws and the catch below
// reports it as "the model had nothing to say" — a misconfiguration wearing
// the disguise of a slow model.
const fetchImpl = stubFetch('occupancy handler')
const variants = await createExpander({ ...MODEL, fetchImpl, timeoutMs: Number.NaN }).expand('q')
assert.deepEqual(variants, ['q', 'occupancy handler'])
})
test('a malformed payload degrades rather than throwing', async () => {
const fetchImpl = async () => ({ ok: true, status: 200, json: async () => ({}) })
assert.deepEqual(await createExpander({ ...MODEL, fetchImpl }).expand('q'), ['q'])
})
test('an empty or oversized query is not sent at all', async () => {
const fetchImpl = stubFetch('variant one')
const expander = createExpander({ ...MODEL, fetchImpl })
assert.deepEqual(await expander.expand(' '), [''])
assert.deepEqual(await expander.expand('x'.repeat(600)), ['x'.repeat(600)])
assert.equal(fetchImpl.calls.length, 0, 'nothing worth asking about')
})
test('caller cancellation stops expansion and returns the original', async () => {
const controller = new AbortController()
controller.abort()
const fetchImpl = stubFetch('variant one')
assert.deepEqual(await createExpander({ ...MODEL, fetchImpl }).expand('q', controller.signal), ['q'])
assert.equal(fetchImpl.calls.length, 0)
})