mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-12 02:02:13 +03:00
* feat(sse): unified media-part detection helper (image+audio, input_image) * refactor(guardrails): extractImageParts/comboStructure delegate to unified media detector * fix(sse): media detector — audio parts no longer shadow sibling/nested image indicators * fix(guardrails): close extract↔replace contract for input_image (allowlist + splice) * perf(guardrails): skip media traversal when bridge disabled; short-circuit combo image check * feat(guardrails): in-memory LRU bridge cache (sha256 keyed) * feat(settings): modalityBridge* schema with legacy visionBridge* fallback * feat(db): migrate visionBridge* settings to modalityBridge* (idempotent) * refactor(guardrails): harden bridge cache key/config + settings resolution (review minors) * feat(guardrails): vision bridge mode selector (auto/describe/reroute) short-circuit * feat(guardrails): task-aware vision description prompt (default on) * feat(guardrails): describe-path cache integration * docs(guardrails): review polish — cache-key coupling notes + helper header * feat(guardrails): in-memory bridge stats + modality-bridge response header * feat(api): modality bridge stats endpoint + header wiring in chat handler * docs(guardrails): document modality bridge mode/task-aware/cache/header + stats endpoint * chore: untrack _tasks symlink (inherited from base tip; blocks pre-commit tracked-artifacts gate) * fix(db): renumber modality bridge migration 139->140 (base renumbered ccr_blocks to 139) * docs(guardrails): migration filename touch-up 139->140 * docs(db): stale comment touch-ups after 139->140 renumber and #9688 landing * fix(db): renumber modality bridge migration 140->141 (base renumbered connection_runtime_state to 140) * test(db): migration test titles 139->141 --------- Co-authored-by: diegosouzapw <diegosouzapw@users.noreply.github.com>
64 lines
2.3 KiB
TypeScript
64 lines
2.3 KiB
TypeScript
import { test } from "node:test";
|
|
import assert from "node:assert";
|
|
|
|
import {
|
|
BridgeCache,
|
|
bridgeCacheKey,
|
|
getSharedBridgeCacheFor,
|
|
} from "../../src/lib/guardrails/modalityBridge/bridgeCache.ts";
|
|
import { resolveVisionBridgeRuntimeSettings } from "../../src/shared/constants/modalityBridgeDefaults.ts";
|
|
|
|
test("key is stable sha256 of content+prompt+model", () => {
|
|
const a = bridgeCacheKey("data:image/png;base64,AAA", "describe", "gpt-4o-mini");
|
|
const b = bridgeCacheKey("data:image/png;base64,AAA", "describe", "gpt-4o-mini");
|
|
assert.equal(a, b);
|
|
assert.match(a, /^[a-f0-9]{64}$/);
|
|
assert.notEqual(a, bridgeCacheKey("data:image/png;base64,AAA", "other", "gpt-4o-mini"));
|
|
});
|
|
|
|
test("key framing prevents boundary-shift collisions between fields", () => {
|
|
// Without length-prefix framing ("ab","c") and ("a","bc") would hash the
|
|
// same concatenated bytes.
|
|
assert.notEqual(bridgeCacheKey("ab", "c", "m"), bridgeCacheKey("a", "bc", "m"));
|
|
assert.notEqual(bridgeCacheKey("x", "yz", "m"), bridgeCacheKey("x", "y", "zm"));
|
|
});
|
|
|
|
test("get/set roundtrip and TTL expiry", () => {
|
|
let now = 1000;
|
|
const cache = new BridgeCache({ maxEntries: 10, ttlMs: 500, now: () => now });
|
|
cache.set("k1", "desc");
|
|
assert.equal(cache.get("k1"), "desc");
|
|
now = 1600;
|
|
assert.equal(cache.get("k1"), undefined);
|
|
});
|
|
|
|
test("LRU evicts oldest when full", () => {
|
|
const cache = new BridgeCache({ maxEntries: 2, ttlMs: 60000, now: () => 0 });
|
|
cache.set("a", "1");
|
|
cache.set("b", "2");
|
|
cache.get("a");
|
|
cache.set("c", "3");
|
|
assert.equal(cache.get("b"), undefined);
|
|
assert.equal(cache.get("a"), "1");
|
|
});
|
|
|
|
test("getSharedBridgeCacheFor reuses the instance for the same config and recreates on change", () => {
|
|
const base = resolveVisionBridgeRuntimeSettings({});
|
|
const a = getSharedBridgeCacheFor(base);
|
|
const b = getSharedBridgeCacheFor({ ...base });
|
|
assert.equal(a, b);
|
|
|
|
const c = getSharedBridgeCacheFor({ ...base, cacheTtlMinutes: base.cacheTtlMinutes + 5 });
|
|
assert.notEqual(c, a);
|
|
|
|
const d = getSharedBridgeCacheFor({ ...base, cacheTtlMinutes: base.cacheTtlMinutes + 5 });
|
|
assert.equal(d, c);
|
|
|
|
const e = getSharedBridgeCacheFor({
|
|
...base,
|
|
cacheTtlMinutes: base.cacheTtlMinutes + 5,
|
|
cacheMaxEntries: base.cacheMaxEntries + 1,
|
|
});
|
|
assert.notEqual(e, d);
|
|
});
|