Skip to content
Open
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
3 changes: 2 additions & 1 deletion src/logic/cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ export class Cache<T = any> {
private ttlMs: number;

constructor(ttlSeconds?: number) {
this.ttlMs = (ttlSeconds ?? Number(process.env.CACHE_TTL_SECONDS) ?? 300) * 1000;
const envTtl = Number(process.env.CACHE_TTL_SECONDS);
this.ttlMs = (ttlSeconds ?? (Number.isFinite(envTtl) ? envTtl : 300)) * 1000;
}

/**
Expand Down
11 changes: 6 additions & 5 deletions src/logic/synth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,13 +106,14 @@ export async function synthesise(
const choice = body.choices?.[0];
const usage = body.usage ?? {};

const answerText = choice?.message?.content;
if (!answerText) {
throw new Error("OpenAI returned an empty response");
}
return {
answer: choice?.message?.content ?? "No answer generated.",
answer: answerText,
confidence: scoreConfidence(sources),
tokens: {
in: usage.prompt_tokens ?? 0,
out: usage.completion_tokens ?? 0,
},
tokens: { in: usage.prompt_tokens ?? 0, out: usage.completion_tokens ?? 0 },
model,
};
}
19 changes: 19 additions & 0 deletions tests/logic/cache.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,25 @@ describe("Cache", () => {
test("hitRate is 0 when no operations", () => {
expect(cache.stats().hitRate).toBe(0);
});

test("defaults to 300s TTL when no args and env var unset", () => {
const saved = process.env.CACHE_TTL_SECONDS;
delete process.env.CACHE_TTL_SECONDS;
const c = new Cache<string>();
c.set("k", "v");
// Should be retrievable immediately (not expired)
expect(c.get("k")).not.toBeNull();
expect(c.stats().size).toBe(1);
if (saved !== undefined) process.env.CACHE_TTL_SECONDS = saved;
});

test("respects CACHE_TTL_SECONDS env var", () => {
process.env.CACHE_TTL_SECONDS = "1";
const c = new Cache<string>();
c.set("k", "v");
expect(c.get("k")).not.toBeNull();
delete process.env.CACHE_TTL_SECONDS;
});
});

describe("Cache.normalizeKey", () => {
Expand Down
6 changes: 6 additions & 0 deletions tests/logic/synth.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,4 +76,10 @@ describe("scoreConfidence", () => {

expect(scoreAgree).toBeGreaterThan(scoreDisagree);
});

test("single source scores lower than multiple sources", () => {
const one = [makeSource()];
const three = [makeSource(), makeSource(), makeSource()];
expect(scoreConfidence(three)).toBeGreaterThan(scoreConfidence(one));
});
});