mirror of
https://github.com/garrytan/gbrain.git
synced 2026-07-27 22:15:33 +00:00
Three backlog fixes: - #1610: voyageCompatFetch/zeroEntropyCompatFetch read the response body ONCE via text() + JSON.parse instead of resp.clone().json(). On bun < 1.1.27 clone() truncates large bodies (oven-sh/bun#6348), the parse threw, and the catch fell back to the raw provider shape the AI SDK schema rejects — multi-chunk pages died with "Invalid JSON response". Every JSON return path now rebuilds the Response and strips the stale Content-Length/Content-Encoding headers. Shims exported as test seams; behavioral coverage simulates the truncating clone(). - #1484: a bare `gbrain query`/`search` that returns zero results on a multi-source brain now prints a stderr hint naming the source that was actually searched and how to widen scope (--source-id __all__). Fires only when the caller didn't scope explicitly; best-effort (lookup failure is silent). Default scope stays unchanged — widening to __all__ is a separate maintainer policy call. - #1626: hybridSearch's text-vector arm no longer swallows failures dark. The arm only runs when the embedding provider probed available, so a throw (embed timeout, transient pooler error on the searchVector fan-out) now logs the reason via warnOncePerProcess while keeping the keyword fallback — a cross-source __all__ run can no longer collapse to "No results" with zero diagnostics. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
62 lines
2.6 KiB
TypeScript
62 lines
2.6 KiB
TypeScript
/**
|
|
* #1484 — invisible-miss hint. A bare `gbrain query` resolves to a single
|
|
* source (usually 'default'); on a multi-source brain a zero-hit run gave no
|
|
* signal that the answer might live in another source. sourceScopeHint
|
|
* returns the stderr hint exactly when: query/search op + zero results +
|
|
* no explicit scoping param + >1 registered source.
|
|
*/
|
|
|
|
import { describe, expect, test } from 'bun:test';
|
|
import { sourceScopeHint } from '../src/cli.ts';
|
|
import type { BrainEngine } from '../src/core/engine.ts';
|
|
|
|
function fakeEngine(sourceCount: number, fail = false): BrainEngine {
|
|
return {
|
|
executeRaw: async () => {
|
|
if (fail) throw new Error('sources table missing');
|
|
return [{ n: sourceCount }];
|
|
},
|
|
} as unknown as BrainEngine;
|
|
}
|
|
|
|
describe('sourceScopeHint (#1484)', () => {
|
|
test('fires on a bare zero-hit query against a multi-source brain', async () => {
|
|
const hint = await sourceScopeHint('query', {}, 'default', fakeEngine(3), []);
|
|
expect(hint).toContain('3 sources');
|
|
expect(hint).toContain('"default"');
|
|
expect(hint).toContain('--source-id __all__');
|
|
});
|
|
|
|
test('fires for search too', async () => {
|
|
const hint = await sourceScopeHint('search', {}, 'wiki', fakeEngine(2), []);
|
|
expect(hint).toContain('"wiki"');
|
|
});
|
|
|
|
test('silent when results were found', async () => {
|
|
expect(await sourceScopeHint('query', {}, 'default', fakeEngine(3), [{ slug: 'a' }])).toBeNull();
|
|
});
|
|
|
|
test('silent when the caller scoped explicitly', async () => {
|
|
expect(await sourceScopeHint('query', { source_id: 'wiki' }, 'wiki', fakeEngine(3), [])).toBeNull();
|
|
expect(await sourceScopeHint('query', { source: 'wiki' }, 'wiki', fakeEngine(3), [])).toBeNull();
|
|
expect(await sourceScopeHint('query', { all_sources: true }, '__all__', fakeEngine(3), [])).toBeNull();
|
|
});
|
|
|
|
test('silent when the resolved scope is already __all__', async () => {
|
|
expect(await sourceScopeHint('query', {}, '__all__', fakeEngine(3), [])).toBeNull();
|
|
});
|
|
|
|
test('silent on a single-source brain', async () => {
|
|
expect(await sourceScopeHint('query', {}, 'default', fakeEngine(1), [])).toBeNull();
|
|
});
|
|
|
|
test('silent for non-search ops and non-array results', async () => {
|
|
expect(await sourceScopeHint('get_stats', {}, 'default', fakeEngine(3), [])).toBeNull();
|
|
expect(await sourceScopeHint('query', {}, 'default', fakeEngine(3), { rows: [] })).toBeNull();
|
|
});
|
|
|
|
test('best-effort: sources lookup failure returns null, never throws', async () => {
|
|
expect(await sourceScopeHint('query', {}, 'default', fakeEngine(3, true), [])).toBeNull();
|
|
});
|
|
});
|