mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-09-15 11:22:15 +03:00
Merged, with one column-reconciliation gap closed. The fail-closed reasoning is right and the comments carry it well: a stored snapshot whose cues were replaced by `[redacted-video-transcript]` must not be rehydrated as continuation history, because forwarding placeholder text upstream as if it were the client's real turn is worse than making the client resend. Treating it exactly like `previous_response_not_found` means no new client-visible behaviour to document. Migration 173 does not collide — the tip runs to 172. **What I added:** `video_content_removed` to `ensureCallLogsColumns` in `src/lib/db/schemaColumns.ts`, plus a case in `tests/unit/db-schema-columns-split.test.ts`. `resolvePreviousResponseState` now SELECTs that column on every `previous_response_id` lookup. Migration 173 creates it, but this repo carries a separate reconciliation path for lineages that skipped a migration — and on such a database the SELECT would throw `no such column: video_content_removed` instead of failing closed. That is the same hole #12470 closed for `provider_connections.last_ping_at` earlier today, so the pattern was fresh. Verified red-then-green: stubbing the new reconciliation out drops the suite to 8/9; restored, 9/9. Validated on `release/v3.8.51`: `responses-continuation-store`, `save-call-log-persistence`, `video-bridge-log-redaction` and `db-schema-columns-split` all green (54 focused tests, 0 failures). `typecheck:core` and `lint` clean. The integration run logs `[DB] Added call_logs.video_content_removed column`, which is the reconciliation firing on a fresh test database.
245 lines
7.4 KiB
TypeScript
245 lines
7.4 KiB
TypeScript
import test from "node:test";
|
|
import assert from "node:assert/strict";
|
|
import { getDbInstance } from "../../src/lib/db/core.ts";
|
|
import { saveCallLog, getCallLogs } from "../../src/lib/usage/callLogs.ts";
|
|
|
|
test("saveCallLog persists to DB with correlationId", async () => {
|
|
const db = getDbInstance();
|
|
const testId = `test-corr-${Date.now()}`;
|
|
|
|
await saveCallLog({
|
|
id: testId,
|
|
method: "POST",
|
|
path: "/v1/chat/completions",
|
|
status: 200,
|
|
model: "test-model",
|
|
provider: "test-provider",
|
|
duration: 1234,
|
|
tokens: { in: 10, out: 5 },
|
|
correlationId: "test-correlation-id-123",
|
|
sourceFormat: "openai",
|
|
targetFormat: "openai",
|
|
});
|
|
|
|
const row = db
|
|
.prepare("SELECT id, correlation_id, status, model FROM call_logs WHERE id = ?")
|
|
.get(testId) as Record<string, unknown>;
|
|
assert.ok(row, "row should exist in call_logs");
|
|
assert.equal(row.id, testId);
|
|
assert.equal(row.correlation_id, "test-correlation-id-123");
|
|
assert.equal(row.status, 200);
|
|
assert.equal(row.model, "test-model");
|
|
|
|
db.prepare("DELETE FROM call_logs WHERE id = ?").run(testId);
|
|
});
|
|
|
|
test("saveCallLog persists null correlationId when not provided", async () => {
|
|
const db = getDbInstance();
|
|
const testId = `test-nocorr-${Date.now()}`;
|
|
|
|
await saveCallLog({
|
|
id: testId,
|
|
method: "POST",
|
|
path: "/v1/chat/completions",
|
|
status: 404,
|
|
model: "test-model-2",
|
|
provider: "test-provider",
|
|
duration: 500,
|
|
tokens: {},
|
|
});
|
|
|
|
const row = db
|
|
.prepare("SELECT id, correlation_id FROM call_logs WHERE id = ?")
|
|
.get(testId) as Record<string, unknown>;
|
|
assert.ok(row, "row should exist");
|
|
assert.equal(row.correlation_id, null, "correlation_id should be null when not provided");
|
|
|
|
db.prepare("DELETE FROM call_logs WHERE id = ?").run(testId);
|
|
});
|
|
|
|
test("getCallLogs returns correlationId", async () => {
|
|
const db = getDbInstance();
|
|
const testId = `test-getcid-${Date.now()}`;
|
|
|
|
await saveCallLog({
|
|
id: testId,
|
|
method: "POST",
|
|
path: "/v1/chat/completions",
|
|
status: 200,
|
|
model: "test-model-3",
|
|
provider: "test-provider",
|
|
duration: 100,
|
|
tokens: { in: 20, out: 10 },
|
|
correlationId: "cid-roundtrip-test",
|
|
});
|
|
|
|
const logs = await getCallLogs({ limit: 100 });
|
|
const found = logs.find((l: { id: string }) => l.id === testId);
|
|
assert.ok(found, "log entry should be found via getCallLogs");
|
|
assert.equal(found.correlationId, "cid-roundtrip-test");
|
|
|
|
db.prepare("DELETE FROM call_logs WHERE id = ?").run(testId);
|
|
});
|
|
|
|
test("call_logs table has correlation_id column", () => {
|
|
const db = getDbInstance();
|
|
const columns = db.prepare("PRAGMA table_info(call_logs)").all() as { name: string }[];
|
|
const colNames = columns.map((c) => c.name);
|
|
assert.ok(colNames.includes("correlation_id"), "call_logs should have correlation_id column");
|
|
|
|
const indexes = db.prepare("PRAGMA index_list(call_logs)").all() as { name: string }[];
|
|
const idxNames = indexes.map((i) => i.name);
|
|
assert.ok(
|
|
idxNames.includes("idx_cl_correlation_id"),
|
|
"call_logs should have idx_cl_correlation_id index"
|
|
);
|
|
});
|
|
|
|
test("call_logs table has model_pinned column", () => {
|
|
const db = getDbInstance();
|
|
const columns = db.prepare("PRAGMA table_info(call_logs)").all() as { name: string }[];
|
|
const colNames = columns.map((c) => c.name);
|
|
assert.ok(colNames.includes("model_pinned"), "call_logs should have model_pinned column");
|
|
});
|
|
|
|
test("saveCallLog persists modelPinned=true as 1", async () => {
|
|
const db = getDbInstance();
|
|
const testId = `test-pinned-${Date.now()}`;
|
|
|
|
await saveCallLog({
|
|
id: testId,
|
|
method: "POST",
|
|
path: "/v1/chat/completions",
|
|
status: 200,
|
|
model: "pinned-model",
|
|
provider: "test-provider",
|
|
duration: 500,
|
|
tokens: { in: 10, out: 5 },
|
|
modelPinned: true,
|
|
});
|
|
|
|
const row = db
|
|
.prepare("SELECT id, model_pinned FROM call_logs WHERE id = ?")
|
|
.get(testId) as Record<string, unknown>;
|
|
assert.ok(row, "row should exist");
|
|
assert.equal(row.model_pinned, 1, "model_pinned should be 1 when modelPinned=true");
|
|
|
|
db.prepare("DELETE FROM call_logs WHERE id = ?").run(testId);
|
|
});
|
|
|
|
test("saveCallLog persists modelPinned=false as 0", async () => {
|
|
const db = getDbInstance();
|
|
const testId = `test-notpinned-${Date.now()}`;
|
|
|
|
await saveCallLog({
|
|
id: testId,
|
|
method: "POST",
|
|
path: "/v1/chat/completions",
|
|
status: 200,
|
|
model: "normal-model",
|
|
provider: "test-provider",
|
|
duration: 500,
|
|
tokens: { in: 10, out: 5 },
|
|
modelPinned: false,
|
|
});
|
|
|
|
const row = db
|
|
.prepare("SELECT id, model_pinned FROM call_logs WHERE id = ?")
|
|
.get(testId) as Record<string, unknown>;
|
|
assert.ok(row, "row should exist");
|
|
assert.equal(row.model_pinned, 0, "model_pinned should be 0 when modelPinned=false");
|
|
|
|
db.prepare("DELETE FROM call_logs WHERE id = ?").run(testId);
|
|
});
|
|
|
|
test("call_logs table has video_content_removed column", () => {
|
|
const db = getDbInstance();
|
|
const columns = db.prepare("PRAGMA table_info(call_logs)").all() as { name: string }[];
|
|
const colNames = columns.map((c) => c.name);
|
|
assert.ok(
|
|
colNames.includes("video_content_removed"),
|
|
"call_logs should have video_content_removed column"
|
|
);
|
|
});
|
|
|
|
test("saveCallLog persists videoContentRemoved=true as 1 (#12150 P2)", async () => {
|
|
const db = getDbInstance();
|
|
const testId = `test-videoremoved-${Date.now()}`;
|
|
|
|
await saveCallLog({
|
|
id: testId,
|
|
method: "POST",
|
|
path: "/v1/responses",
|
|
status: 200,
|
|
model: "video-model",
|
|
provider: "test-provider",
|
|
duration: 500,
|
|
tokens: { in: 10, out: 5 },
|
|
videoContentRemoved: true,
|
|
});
|
|
|
|
const row = db
|
|
.prepare("SELECT id, video_content_removed FROM call_logs WHERE id = ?")
|
|
.get(testId) as Record<string, unknown>;
|
|
assert.ok(row, "row should exist");
|
|
assert.equal(
|
|
row.video_content_removed,
|
|
1,
|
|
"video_content_removed should be 1 when videoContentRemoved=true"
|
|
);
|
|
|
|
db.prepare("DELETE FROM call_logs WHERE id = ?").run(testId);
|
|
});
|
|
|
|
test("saveCallLog defaults video_content_removed to 0 when absent (#12150 P2)", async () => {
|
|
const db = getDbInstance();
|
|
const testId = `test-novideoremoved-${Date.now()}`;
|
|
|
|
await saveCallLog({
|
|
id: testId,
|
|
method: "POST",
|
|
path: "/v1/chat/completions",
|
|
status: 200,
|
|
model: "normal-model",
|
|
provider: "test-provider",
|
|
duration: 500,
|
|
tokens: { in: 10, out: 5 },
|
|
});
|
|
|
|
const row = db
|
|
.prepare("SELECT id, video_content_removed FROM call_logs WHERE id = ?")
|
|
.get(testId) as Record<string, unknown>;
|
|
assert.ok(row, "row should exist");
|
|
assert.equal(
|
|
row.video_content_removed,
|
|
0,
|
|
"video_content_removed should default to 0 when not provided"
|
|
);
|
|
|
|
db.prepare("DELETE FROM call_logs WHERE id = ?").run(testId);
|
|
});
|
|
|
|
test("getCallLogs returns modelPinned boolean", async () => {
|
|
const db = getDbInstance();
|
|
const testId = `test-pinned-roundtrip-${Date.now()}`;
|
|
|
|
await saveCallLog({
|
|
id: testId,
|
|
method: "POST",
|
|
path: "/v1/chat/completions",
|
|
status: 200,
|
|
model: "pinned-model-rt",
|
|
provider: "test-provider",
|
|
duration: 100,
|
|
tokens: { in: 20, out: 10 },
|
|
modelPinned: true,
|
|
});
|
|
|
|
const logs = await getCallLogs({ limit: 100 });
|
|
const found = logs.find((l: { id: string }) => l.id === testId);
|
|
assert.ok(found, "log entry should be found via getCallLogs");
|
|
assert.equal(found.modelPinned, true, "getCallLogs should return modelPinned as boolean true");
|
|
|
|
db.prepare("DELETE FROM call_logs WHERE id = ?").run(testId);
|
|
});
|