Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions src/review/rag.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,8 @@ export function ragDimensionsFromEnv(value: string | undefined): number {
}

export function ragEmbedBatchFromEnv(value: string | undefined): number {
const batch = Number(value);
return Number.isFinite(batch) && batch > 0 ? Math.floor(batch) : EMBED_BATCH;
const batch = Math.floor(Number(value));
return Number.isFinite(batch) && batch > 0 ? batch : EMBED_BATCH;
}

// ── Filtering: index CODE, not content/data corpora (the primary free-tier cost guard) ───────────
Expand Down Expand Up @@ -298,10 +298,12 @@ export async function embedTexts(
batchSize = EMBED_BATCH,
): Promise<number[][] | null> {
if (!inference || texts.length === 0) return null;
const effectiveBatchSize = Math.floor(batchSize);
if (!Number.isFinite(effectiveBatchSize) || effectiveBatchSize < 1) return null;
try {
const out: number[][] = [];
for (let i = 0; i < texts.length; i += batchSize) {
const batch = texts.slice(i, i + batchSize);
for (let i = 0; i < texts.length; i += effectiveBatchSize) {
const batch = texts.slice(i, i + effectiveBatchSize);
const res = (await inference.run(EMBED_MODEL, { text: batch })) as { data?: number[][] } | null;
const data = res?.data;
// Validate COUNT and DIMENSION: a self-host embedding endpoint can return a structurally-valid response
Expand Down
11 changes: 11 additions & 0 deletions test/unit/rag.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ describe("ragEmbedBatchFromEnv", () => {
expect(ragEmbedBatchFromEnv("")).toBe(96);
expect(ragEmbedBatchFromEnv("not-a-number")).toBe(96);
expect(ragEmbedBatchFromEnv("0")).toBe(96);
expect(ragEmbedBatchFromEnv("0.5")).toBe(96);
expect(ragEmbedBatchFromEnv("-5")).toBe(96);
});
});
Expand Down Expand Up @@ -733,6 +734,16 @@ describe("rag: embedTexts validation branches", () => {
expect(calls).toEqual([96, 54]); // proves the batching loop ran twice
});

it("rejects an invalid batchSize before embedding so a zero step cannot hang", async () => {
const inference: InferenceAdapter = {
run: async () => {
throw new Error("must not call embedding provider for an invalid batch size");
},
};
expect(await embedTexts(inference, ["hi"], RAG_DIMENSIONS, 0)).toBeNull();
expect(await embedTexts(inference, ["hi"], RAG_DIMENSIONS, Number.NaN)).toBeNull();
});

it("honors a configured batchSize override instead of the EMBED_BATCH=96 default (self-host GPU tuning)", async () => {
const calls: number[] = [];
const inference: InferenceAdapter = {
Expand Down