mirror of
https://github.com/garrytan/gbrain.git
synced 2026-08-14 00:48:18 +00:00
* feat(recipes): add reranker touchpoint to OpenRouter (#2164) OpenRouter's POST /api/v1/rerank is wire-compatible with gateway.rerank() ({query, documents, model} → {results: [{index, relevance_score}]}). This adds a recipe-only reranker touchpoint declaring four models: - cohere/rerank-v3.5 (default; $0.001/search) - cohere/rerank-4-fast ($0.002/search, 32K context) - cohere/rerank-4-pro ($0.0025/search, SOTA quality) - nvidia/llama-nemotron-rerank-vl-1b-v2:free (multimodal) Unlike embedding/chat, the reranker path strictly enforces the models allowlist — the openai-compat extended-model bypass does not apply. New rerank models must be added to this recipe before they can be called. The cost_per_1m_tokens_usd value is a pseudo-rate for the budget tracker's chars/4 heuristic — Cohere bills per-search, not per-token. At ~4K chars the estimated cost is in the right ballpark. Recipe-only change; no gateway or search-layer modifications. gateway auto-concatenates path → .../api/v1/rerank. Adds hermetic unit test (test/openrouter-reranker-recipe.test.ts) covering shape, models, default_model, path, max_payload_bytes, default_timeout_ms, and cost field. No DB, no env mutation — survives the parallel 8-shard fan-out. Verified: bun run verify (30/30 green); 285 targeted recipe+rerank+budget tests pass. Co-authored-by: Hippityy <Hippityy@users.noreply.github.com> * test(facts): pin gateway to 1536d in facts-engine.test.ts beforeAll Shard-composition hermeticity fix. The legacy preload's beforeEach only re-applies the 1536-d gateway default before each TEST, not before a file's beforeAll — so when the previous file in the shard resets the gateway in its teardown (e.g. test/providers-test-model-base-url.test.ts via afterEach), this file's initSchema() sized facts.embedding at the 1280-d production default and the 1536-d fixture inserts threw 'expected 1280 dimensions, not 1536' (CI shard 1 failure on #3302). Same pattern as test/consolidate-valid-until.test.ts. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Ryan Xie <64182766+Hippityy@users.noreply.github.com> Co-authored-by: Hippityy <Hippityy@users.noreply.github.com> Co-authored-by: Garry Tan <garrytan@gmail.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
45 lines
1.8 KiB
TypeScript
45 lines
1.8 KiB
TypeScript
import { describe, test, expect } from 'bun:test';
|
|
import { getRecipe } from '../src/core/ai/recipes/index.ts';
|
|
|
|
describe('OpenRouter recipe — reranker touchpoint', () => {
|
|
test('declares a reranker touchpoint', () => {
|
|
const r = getRecipe('openrouter');
|
|
expect(r).toBeDefined();
|
|
expect(r!.touchpoints.reranker).toBeDefined();
|
|
});
|
|
|
|
test('models list includes all supported IDs (incl. NVIDIA :free suffix)', () => {
|
|
const m = getRecipe('openrouter')!.touchpoints.reranker!.models;
|
|
expect(m).toContain('cohere/rerank-v3.5');
|
|
expect(m).toContain('cohere/rerank-4-fast');
|
|
expect(m).toContain('cohere/rerank-4-pro');
|
|
// The :free suffix must appear in full — gateway.rerank() does exact
|
|
// string matching against the allowlist (no v0.31.12 extended-model bypass
|
|
// on the rerank path), so truncating to `nvidia/.../v2` would 403.
|
|
expect(m).toContain('nvidia/llama-nemotron-rerank-vl-1b-v2:free');
|
|
});
|
|
|
|
test('default_model is cohere/rerank-v3.5', () => {
|
|
const tp = getRecipe('openrouter')!.touchpoints.reranker!;
|
|
expect(tp.default_model).toBe('cohere/rerank-v3.5');
|
|
expect(tp.models).toContain(tp.default_model);
|
|
});
|
|
|
|
test('path is /rerank (NOT ZeroEntropy default /models/rerank)', () => {
|
|
const tp = getRecipe('openrouter')!.touchpoints.reranker!;
|
|
expect(tp.path).toBe('/rerank');
|
|
});
|
|
|
|
test('max_payload_bytes and timeout match plan', () => {
|
|
const tp = getRecipe('openrouter')!.touchpoints.reranker!;
|
|
expect(tp.max_payload_bytes).toBe(5_000_000);
|
|
expect(tp.default_timeout_ms).toBe(5_000);
|
|
});
|
|
|
|
test('cost_per_1m_tokens_usd is set (pseudo-rate for per-search billing)', () => {
|
|
const tp = getRecipe('openrouter')!.touchpoints.reranker!;
|
|
expect(typeof tp.cost_per_1m_tokens_usd).toBe('number');
|
|
expect(tp.cost_per_1m_tokens_usd).toBeGreaterThan(0);
|
|
});
|
|
});
|