mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-04 14:22:09 +03:00
Provider-specific caching enhancements:
OpenAI:
- Auto-generate prompt_cache_key from message prefix hash
- Key format: omni-{prefix_hash_32chars}
- Preserves client-provided keys (doesn't override)
Gemini:
- Preserve cachedContent ID if provided by client
- Enables explicit Gemini caching for long prompts
- cachedContentTokenCount already tracked in responses
86 lines
2.2 KiB
TypeScript
86 lines
2.2 KiB
TypeScript
import crypto from "crypto";
|
|
|
|
interface Message {
|
|
role: string;
|
|
content: string | unknown[];
|
|
}
|
|
|
|
interface PrefixAnalysis {
|
|
prefixEndIdx: number;
|
|
prefixHash: string;
|
|
prefixTokens: number;
|
|
prefixType: "system_only" | "system_and_tools" | "system_tools_history";
|
|
confidence: number;
|
|
}
|
|
|
|
function normalizeContent(content: string | unknown[]): string {
|
|
if (typeof content === "string") return content;
|
|
return JSON.stringify(content);
|
|
}
|
|
|
|
function estimateTokens(text: string): number {
|
|
return Math.ceil(text.length / 4);
|
|
}
|
|
|
|
export function analyzePrefix(messages: Message[]): PrefixAnalysis {
|
|
if (!Array.isArray(messages) || messages.length === 0) {
|
|
return {
|
|
prefixEndIdx: -1,
|
|
prefixHash: "",
|
|
prefixTokens: 0,
|
|
prefixType: "system_only",
|
|
confidence: 0,
|
|
};
|
|
}
|
|
|
|
let prefixEndIdx = -1;
|
|
let prefixType: PrefixAnalysis["prefixType"] = "system_only";
|
|
let confidence = 0.5;
|
|
|
|
for (let i = 0; i < messages.length; i++) {
|
|
const msg = messages[i];
|
|
const role = msg.role || "user";
|
|
|
|
if (role === "system") {
|
|
prefixEndIdx = i;
|
|
prefixType = "system_only";
|
|
confidence = 0.9;
|
|
} else if (role === "tool" || (role === "assistant" && Array.isArray(msg.content))) {
|
|
prefixEndIdx = i;
|
|
prefixType = "system_and_tools";
|
|
confidence = 0.8;
|
|
} else if (role === "assistant") {
|
|
prefixEndIdx = i;
|
|
prefixType = "system_tools_history";
|
|
confidence = 0.7;
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
|
|
const prefixMessages = messages.slice(0, prefixEndIdx + 1);
|
|
const prefixText = prefixMessages.map((m) => normalizeContent(m.content)).join("\n");
|
|
const prefixHash = crypto.createHash("sha256").update(prefixText).digest("hex");
|
|
const prefixTokens = estimateTokens(prefixText);
|
|
|
|
return {
|
|
prefixEndIdx,
|
|
prefixHash,
|
|
prefixTokens,
|
|
prefixType,
|
|
confidence,
|
|
};
|
|
}
|
|
|
|
export function shouldInjectCacheControl(analysis: PrefixAnalysis, minTokens = 1024): boolean {
|
|
return analysis.prefixTokens >= minTokens && analysis.confidence >= 0.7;
|
|
}
|
|
|
|
export function generatePromptCacheKey(messages: Message[]): string {
|
|
const analysis = analyzePrefix(messages);
|
|
if (analysis.prefixHash) {
|
|
return `omni-${analysis.prefixHash.slice(0, 32)}`;
|
|
}
|
|
return "";
|
|
}
|