Files
2026-07-13 13:39:12 +08:00

1120 lines
39 KiB
TypeScript

/**
* OmniRoute MCP Advanced Tools — 13 intelligence tools that differentiate
* OmniRoute from all other AI gateways.
*
* Tools:
* 1. omniroute_simulate_route — Dry-run routing simulation
* 2. omniroute_set_budget_guard — Session budget with degrade/block/alert
* 3. omniroute_set_routing_strategy — Runtime strategy switch for combos
* 4. omniroute_set_resilience_profile — Circuit breaker/retry profiles
* 5. omniroute_test_combo — Live test each provider in a combo
* 6. omniroute_get_provider_metrics — Detailed per-provider metrics
* 7. omniroute_best_combo_for_task — AI-powered combo recommendation
* 8. omniroute_explain_route — Post-hoc routing decision explainer
* 9. omniroute_get_session_snapshot — Full session state snapshot
* 10. omniroute_db_health_check — Diagnose and repair DB state drift
* 11. omniroute_sync_pricing — Sync provider pricing from external source
*/
import { logToolCall } from "../audit.ts";
import { getMcpHttpAuthHeadersForInternalFetch } from "../httpAuthContext.ts";
import { normalizeQuotaResponse } from "../../../src/shared/contracts/quota.ts";
import { resolveOmniRouteBaseUrl } from "../../../src/shared/utils/resolveOmniRouteBaseUrl.ts";
import {
getComboModelProvider,
getComboModelString,
getComboStepTarget,
} from "../../../src/lib/combos/steps.ts";
import type {
AutoRoutingStrategyValue,
RoutingStrategyValue,
} from "../../../src/shared/constants/routingStrategies.ts";
import { normalizeRoutingStrategy } from "../../../src/shared/constants/routingStrategies.ts";
const OMNIROUTE_BASE_URL = resolveOmniRouteBaseUrl();
const OMNIROUTE_API_KEY = process.env.OMNIROUTE_API_KEY || "";
async function apiFetch(path: string, options: RequestInit = {}): Promise<unknown> {
const url = `${OMNIROUTE_BASE_URL}${path}`;
const headers: Record<string, string> = {
"Content-Type": "application/json",
// Static env key is only a fallback; the per-caller MCP identity forwarded via
// withMcpHttpAuthContext must win over it (#5819).
...(OMNIROUTE_API_KEY ? { Authorization: `Bearer ${OMNIROUTE_API_KEY}` } : {}),
...getMcpHttpAuthHeadersForInternalFetch(),
...((options.headers as Record<string, string>) || {}),
};
const response = await fetch(url, { ...options, headers, signal: AbortSignal.timeout(30000) });
if (!response.ok) {
const text = await response.text().catch(() => "Unknown error");
throw new Error(`API [${response.status}]: ${text}`);
}
return response.json();
}
type JsonRecord = Record<string, unknown>;
interface ComboModel {
provider: string;
model: string;
inputCostPer1M: number;
}
function isRecord(value: unknown): value is JsonRecord {
return !!value && typeof value === "object" && !Array.isArray(value);
}
function toRecord(value: unknown): JsonRecord {
return isRecord(value) ? value : {};
}
function toArrayOfRecords(value: unknown): JsonRecord[] {
return Array.isArray(value) ? value.filter(isRecord) : [];
}
function toString(value: unknown, fallback = ""): string {
return typeof value === "string" ? value : fallback;
}
function toNumber(value: unknown, fallback = 0): number {
const parsed =
typeof value === "number"
? value
: typeof value === "string" && value.trim().length > 0
? Number(value)
: Number.NaN;
return Number.isFinite(parsed) ? parsed : fallback;
}
function toBoolean(value: unknown, fallback = false): boolean {
return typeof value === "boolean" ? value : fallback;
}
function getComboModels(combo: JsonRecord): ComboModel[] {
const directModels = toArrayOfRecords(combo.models);
const nestedModels = toArrayOfRecords(toRecord(combo.data).models);
const sourceModels = directModels.length > 0 ? directModels : nestedModels;
return sourceModels.map((model) => ({
provider: getComboModelProvider(model) || (getComboModelString(model) ? "unknown" : "combo"),
model: getComboModelString(model) || getComboStepTarget(model) || "",
inputCostPer1M: toNumber(model.inputCostPer1M, 3.0),
}));
}
function normalizeCombosResponse(raw: unknown): JsonRecord[] {
if (Array.isArray(raw)) return raw.filter(isRecord);
const source = toRecord(raw);
return Array.isArray(source.combos) ? source.combos.filter(isRecord) : [];
}
// ============ In-Memory State ============
interface BudgetGuardState {
sessionId: string;
maxCost: number;
action: "degrade" | "block" | "alert";
degradeToTier?: "cheap" | "free";
spent: number;
createdAt: string;
}
let activeBudgetGuard: BudgetGuardState | null = null;
type ResilienceProfileConfig = {
requestQueue: {
requestsPerMinute: number;
minTimeBetweenRequestsMs: number;
concurrentRequests: number;
};
connectionCooldown: {
oauth: {
baseCooldownMs: number;
useUpstreamRetryHints: boolean;
maxBackoffSteps: number;
};
apikey: {
baseCooldownMs: number;
useUpstreamRetryHints: boolean;
maxBackoffSteps: number;
};
};
providerBreaker: {
oauth: {
failureThreshold: number;
resetTimeoutMs: number;
};
apikey: {
failureThreshold: number;
resetTimeoutMs: number;
};
};
};
const RESILIENCE_PROFILES = {
aggressive: {
requestQueue: {
requestsPerMinute: 180,
minTimeBetweenRequestsMs: 100,
concurrentRequests: 16,
},
connectionCooldown: {
oauth: {
baseCooldownMs: 30000,
useUpstreamRetryHints: false,
maxBackoffSteps: 4,
},
apikey: {
baseCooldownMs: 2000,
useUpstreamRetryHints: true,
maxBackoffSteps: 3,
},
},
providerBreaker: {
oauth: {
failureThreshold: 2,
resetTimeoutMs: 30000,
},
apikey: {
failureThreshold: 3,
resetTimeoutMs: 15000,
},
},
},
balanced: {
requestQueue: {
requestsPerMinute: 100,
minTimeBetweenRequestsMs: 200,
concurrentRequests: 10,
},
connectionCooldown: {
oauth: {
baseCooldownMs: 60000,
useUpstreamRetryHints: false,
maxBackoffSteps: 8,
},
apikey: {
baseCooldownMs: 3000,
useUpstreamRetryHints: true,
maxBackoffSteps: 5,
},
},
providerBreaker: {
oauth: {
failureThreshold: 3,
resetTimeoutMs: 60000,
},
apikey: {
failureThreshold: 5,
resetTimeoutMs: 30000,
},
},
},
conservative: {
requestQueue: {
requestsPerMinute: 60,
minTimeBetweenRequestsMs: 350,
concurrentRequests: 6,
},
connectionCooldown: {
oauth: {
baseCooldownMs: 120000,
useUpstreamRetryHints: false,
maxBackoffSteps: 10,
},
apikey: {
baseCooldownMs: 30000,
useUpstreamRetryHints: false,
maxBackoffSteps: 8,
},
},
providerBreaker: {
oauth: {
failureThreshold: 8,
resetTimeoutMs: 120000,
},
apikey: {
failureThreshold: 8,
resetTimeoutMs: 60000,
},
},
},
} satisfies Record<"aggressive" | "balanced" | "conservative", ResilienceProfileConfig>;
const TASK_FITNESS: Record<string, { preferred: string[]; traits: string[] }> = {
coding: { preferred: ["claude", "deepseek", "codex"], traits: ["fast", "code-optimized"] },
review: { preferred: ["claude", "gemini", "openai"], traits: ["analytical", "thorough"] },
planning: { preferred: ["gemini", "claude", "openai"], traits: ["reasoning", "structured"] },
analysis: { preferred: ["gemini", "claude"], traits: ["deep-reasoning", "large-context"] },
debugging: { preferred: ["claude", "deepseek", "codex"], traits: ["code-aware", "fast"] },
documentation: { preferred: ["gemini", "claude", "openai"], traits: ["clear", "structured"] },
};
// ============ Tool Handlers ============
export async function handleSimulateRoute(args: {
model: string;
promptTokenEstimate: number;
combo?: string;
}) {
const start = Date.now();
try {
// Fetch combos and health data for simulation
const [combosRaw, healthRaw, quotaRaw] = await Promise.allSettled([
apiFetch("/api/combos"),
apiFetch("/api/monitoring/health"),
apiFetch("/api/usage/quota"),
]);
const combos = combosRaw.status === "fulfilled" ? normalizeCombosResponse(combosRaw.value) : [];
const health = healthRaw.status === "fulfilled" ? toRecord(healthRaw.value) : {};
const quota =
quotaRaw.status === "fulfilled"
? normalizeQuotaResponse(quotaRaw.value)
: normalizeQuotaResponse({});
// Find target combo
const targetCombo = args.combo
? combos.find(
(combo) => toString(combo.id) === args.combo || toString(combo.name) === args.combo
)
: combos.find((combo) => combo.enabled !== false);
if (!targetCombo) {
return {
content: [
{ type: "text" as const, text: JSON.stringify({ error: "No matching combo found" }) },
],
isError: true,
};
}
const models = getComboModels(targetCombo);
const breakers = toArrayOfRecords(health.circuitBreakers);
const providers = quota.providers;
// Simulate path
const simulatedPath = models.map((model, idx: number) => {
const cb = breakers.find((breaker) => toString(breaker.provider) === model.provider);
const q = providers.find((providerEntry) => providerEntry.provider === model.provider);
const estimatedCost = (args.promptTokenEstimate / 1_000_000) * model.inputCostPer1M;
return {
provider: model.provider,
model: model.model || args.model,
probability: idx === 0 ? 0.85 : 0.15 / Math.max(models.length - 1, 1),
estimatedCost: Math.round(estimatedCost * 10000) / 10000,
healthStatus: toString(cb?.state, "CLOSED"),
quotaAvailable: q?.percentRemaining ?? 100,
};
});
const costs = simulatedPath.map((pathEntry) => pathEntry.estimatedCost);
const result = {
simulatedPath,
fallbackTree: {
primary: simulatedPath[0]?.provider || "unknown",
fallbacks: simulatedPath.slice(1).map((pathEntry) => pathEntry.provider),
worstCaseCost: Math.max(...costs, 0),
bestCaseCost: Math.min(...costs, 0),
},
};
await logToolCall("omniroute_simulate_route", args, result, Date.now() - start, true);
return { content: [{ type: "text" as const, text: JSON.stringify(result, null, 2) }] };
} catch (err) {
const msg = err instanceof Error ? err.message : String(err);
await logToolCall("omniroute_simulate_route", args, null, Date.now() - start, false, msg);
return { content: [{ type: "text" as const, text: `Error: ${msg}` }], isError: true };
}
}
export async function handleSetBudgetGuard(args: {
maxCost: number;
action: "degrade" | "block" | "alert";
degradeToTier?: "cheap" | "free";
}) {
const start = Date.now();
try {
// Get current session cost
let spent = 0;
try {
const analytics = toRecord(await apiFetch("/api/usage/analytics?period=session"));
spent = toNumber(analytics.totalCost, 0);
} catch {
/* ignore if analytics not available */
}
activeBudgetGuard = {
sessionId: `budget_${Date.now()}`,
maxCost: args.maxCost,
action: args.action,
degradeToTier: args.degradeToTier,
spent,
createdAt: new Date().toISOString(),
};
const remaining = Math.max(0, args.maxCost - spent);
const result = {
sessionId: activeBudgetGuard.sessionId,
budgetTotal: args.maxCost,
budgetSpent: Math.round(spent * 10000) / 10000,
budgetRemaining: Math.round(remaining * 10000) / 10000,
action: args.action,
status: remaining <= 0 ? "exceeded" : remaining < args.maxCost * 0.2 ? "warning" : "active",
};
await logToolCall(
"omniroute_set_budget_guard",
{ maxCost: args.maxCost, action: args.action },
result,
Date.now() - start,
true
);
return { content: [{ type: "text" as const, text: JSON.stringify(result, null, 2) }] };
} catch (err) {
const msg = err instanceof Error ? err.message : String(err);
await logToolCall("omniroute_set_budget_guard", args, null, Date.now() - start, false, msg);
return { content: [{ type: "text" as const, text: `Error: ${msg}` }], isError: true };
}
}
export async function handleSetRoutingStrategy(args: {
comboId: string;
strategy: RoutingStrategyValue;
autoRoutingStrategy?: AutoRoutingStrategyValue;
}) {
const start = Date.now();
try {
const combos = normalizeCombosResponse(await apiFetch("/api/combos"));
const combo = combos.find(
(comboEntry) =>
toString(comboEntry.id) === args.comboId || toString(comboEntry.name) === args.comboId
);
if (!combo) {
const msg = `Combo '${args.comboId}' not found`;
await logToolCall(
"omniroute_set_routing_strategy",
args,
null,
Date.now() - start,
false,
msg
);
return { content: [{ type: "text" as const, text: `Error: ${msg}` }], isError: true };
}
const comboId = toString(combo.id);
if (!comboId) {
const msg = "Matched combo has no id";
await logToolCall(
"omniroute_set_routing_strategy",
args,
null,
Date.now() - start,
false,
msg
);
return { content: [{ type: "text" as const, text: `Error: ${msg}` }], isError: true };
}
const comboData = toRecord(combo.data);
const currentConfig = toRecord(
Object.keys(toRecord(combo.config)).length > 0 ? combo.config : comboData.config
);
const normalizedStrategy = normalizeRoutingStrategy(args.strategy);
let nextConfig: JsonRecord | undefined = undefined;
if (normalizedStrategy === "auto" && args.autoRoutingStrategy) {
const currentAutoConfig = toRecord(currentConfig.auto);
nextConfig = {
...currentConfig,
auto: {
...currentAutoConfig,
routerStrategy: args.autoRoutingStrategy,
},
};
}
const payload: JsonRecord = { strategy: normalizedStrategy };
if (nextConfig && Object.keys(nextConfig).length > 0) {
payload.config = nextConfig;
}
const updatedCombo = toRecord(
await apiFetch(`/api/combos/${encodeURIComponent(comboId)}`, {
method: "PUT",
body: JSON.stringify(payload),
})
);
const updatedConfig = toRecord(updatedCombo.config);
const resolvedAutoStrategy =
toString(toRecord(updatedConfig.auto).routerStrategy) ||
(normalizedStrategy === "auto" ? (args.autoRoutingStrategy ?? "rules") : "");
const result = {
success: true,
combo: {
id: toString(updatedCombo.id, comboId),
name: toString(updatedCombo.name, toString(combo.name, comboId)),
strategy: toString(updatedCombo.strategy, normalizedStrategy),
autoRoutingStrategy:
toString(updatedCombo.strategy, normalizedStrategy) === "auto"
? resolvedAutoStrategy
: null,
},
};
await logToolCall("omniroute_set_routing_strategy", args, result, Date.now() - start, true);
return { content: [{ type: "text" as const, text: JSON.stringify(result, null, 2) }] };
} catch (err) {
const msg = err instanceof Error ? err.message : String(err);
await logToolCall("omniroute_set_routing_strategy", args, null, Date.now() - start, false, msg);
return { content: [{ type: "text" as const, text: `Error: ${msg}` }], isError: true };
}
}
export async function handleSetResilienceProfile(args: {
profile: "aggressive" | "balanced" | "conservative";
}) {
const start = Date.now();
try {
const settings = RESILIENCE_PROFILES[args.profile];
if (!settings) {
return {
content: [{ type: "text" as const, text: `Error: Invalid profile "${args.profile}"` }],
isError: true,
};
}
// Apply to OmniRoute via API using the plan-aligned resilience structure.
await apiFetch("/api/resilience", {
method: "PATCH",
body: JSON.stringify(settings),
});
const result = { applied: true, profile: args.profile, settings };
await logToolCall("omniroute_set_resilience_profile", args, result, Date.now() - start, true);
return { content: [{ type: "text" as const, text: JSON.stringify(result, null, 2) }] };
} catch (err) {
const msg = err instanceof Error ? err.message : String(err);
await logToolCall(
"omniroute_set_resilience_profile",
args,
null,
Date.now() - start,
false,
msg
);
return { content: [{ type: "text" as const, text: `Error: ${msg}` }], isError: true };
}
}
export async function handleTestCombo(args: { comboId: string; testPrompt: string }) {
const start = Date.now();
try {
// Get combo details
const combos = normalizeCombosResponse(await apiFetch("/api/combos"));
const combo = combos.find(
(comboEntry) =>
toString(comboEntry.id) === args.comboId || toString(comboEntry.name) === args.comboId
);
if (!combo) {
return {
content: [
{
type: "text" as const,
text: JSON.stringify({ error: `Combo "${args.comboId}" not found` }),
},
],
isError: true,
};
}
const models = getComboModels(combo);
const prompt = (args.testPrompt || "Say hello").slice(0, 200);
// Test each provider in parallel
const results = await Promise.allSettled(
models.map(async (model) => {
const providerStart = Date.now();
try {
const resp = toRecord(
await apiFetch("/v1/chat/completions", {
method: "POST",
body: JSON.stringify({
model: model.model || "auto",
messages: [{ role: "user", content: prompt }],
max_tokens: 50,
stream: false,
"x-provider": model.provider,
}),
})
);
const usage = toRecord(resp.usage);
return {
provider: model.provider,
model: model.model || toString(resp.model, "unknown"),
success: true,
latencyMs: Date.now() - providerStart,
cost: toNumber(resp.cost, 0),
tokenCount: toNumber(usage.prompt_tokens, 0) + toNumber(usage.completion_tokens, 0),
};
} catch (err) {
return {
provider: model.provider,
model: model.model || "unknown",
success: false,
latencyMs: Date.now() - providerStart,
cost: 0,
tokenCount: 0,
error: err instanceof Error ? err.message : String(err),
};
}
})
);
const providerResults = results.map((r) =>
r.status === "fulfilled"
? r.value
: {
provider: "unknown",
model: "unknown",
success: false,
latencyMs: 0,
cost: 0,
tokenCount: 0,
error: "Promise rejected",
}
);
const successful = providerResults.filter((r) => r.success);
const fastest = successful.sort((a, b) => a.latencyMs - b.latencyMs)[0];
const cheapest = successful.sort((a, b) => a.cost - b.cost)[0];
const result = {
results: providerResults,
summary: {
totalProviders: providerResults.length,
successful: successful.length,
fastestProvider: fastest?.provider || "none",
cheapestProvider: cheapest?.provider || "none",
},
};
await logToolCall(
"omniroute_test_combo",
{ comboId: args.comboId },
result.summary,
Date.now() - start,
true
);
return { content: [{ type: "text" as const, text: JSON.stringify(result, null, 2) }] };
} catch (err) {
const msg = err instanceof Error ? err.message : String(err);
await logToolCall("omniroute_test_combo", args, null, Date.now() - start, false, msg);
return { content: [{ type: "text" as const, text: `Error: ${msg}` }], isError: true };
}
}
export async function handleGetProviderMetrics(args: { provider: string }) {
const start = Date.now();
try {
const [healthRaw, quotaRaw, analyticsRaw] = await Promise.allSettled([
apiFetch("/api/monitoring/health"),
apiFetch(`/api/usage/quota?provider=${encodeURIComponent(args.provider)}`),
apiFetch(`/api/usage/analytics?period=session&provider=${encodeURIComponent(args.provider)}`),
]);
const health = healthRaw.status === "fulfilled" ? toRecord(healthRaw.value) : {};
const quota =
quotaRaw.status === "fulfilled"
? normalizeQuotaResponse(quotaRaw.value, { provider: args.provider })
: normalizeQuotaResponse({});
const analytics = analyticsRaw.status === "fulfilled" ? toRecord(analyticsRaw.value) : {};
const cb = toArrayOfRecords(health.circuitBreakers).find(
(breaker) => toString(breaker.provider) === args.provider
);
const providerQuota = quota.providers.find((p) => p.provider === args.provider) || null;
const result = {
provider: args.provider,
successRate: toNumber(analytics.successRate, 1.0),
requestCount: toNumber(analytics.requestCount, 0),
avgLatencyMs: toNumber(analytics.avgLatencyMs, 0),
p50LatencyMs: toNumber(analytics.p50LatencyMs, 0),
p95LatencyMs: toNumber(analytics.p95LatencyMs, 0),
p99LatencyMs: toNumber(analytics.p99LatencyMs, 0),
errorRate: toNumber(analytics.errorRate, 0),
lastError: toString(analytics.lastError) || null,
circuitBreakerState: toString(cb?.state, "CLOSED"),
quotaInfo: providerQuota
? {
used: providerQuota.quotaUsed,
total: providerQuota.quotaTotal,
resetAt: providerQuota.resetAt,
}
: { used: 0, total: null, resetAt: null },
};
await logToolCall("omniroute_get_provider_metrics", args, result, Date.now() - start, true);
return { content: [{ type: "text" as const, text: JSON.stringify(result, null, 2) }] };
} catch (err) {
const msg = err instanceof Error ? err.message : String(err);
await logToolCall("omniroute_get_provider_metrics", args, null, Date.now() - start, false, msg);
return { content: [{ type: "text" as const, text: `Error: ${msg}` }], isError: true };
}
}
export async function handleBestComboForTask(args: {
taskType: string;
budgetConstraint?: number;
latencyConstraint?: number;
}) {
const start = Date.now();
try {
const fitness = TASK_FITNESS[args.taskType] || TASK_FITNESS.coding;
const combos = normalizeCombosResponse(await apiFetch("/api/combos"));
const enabledCombos = combos.filter((combo) => combo.enabled !== false);
if (enabledCombos.length === 0) {
return {
content: [
{ type: "text" as const, text: JSON.stringify({ error: "No enabled combos available" }) },
],
isError: true,
};
}
// Score combos by task fitness
const scored = enabledCombos.map((combo) => {
const models = getComboModels(combo);
let score = 0;
// Provider preference scoring
for (const model of models) {
const prefIdx = fitness.preferred.indexOf(model.provider);
if (prefIdx >= 0) score += (fitness.preferred.length - prefIdx) * 10;
}
// Name-based trait scoring
const name = toString(combo.name).toLowerCase();
for (const trait of fitness.traits) {
if (name.includes(trait)) score += 5;
}
// Check if it's a free combo
const isFree =
name.includes("free") ||
models.every((model) => model.provider.toLowerCase().includes("free"));
return { combo, score, isFree };
});
scored.sort((a, b) => b.score - a.score);
const best = scored[0];
const alternatives = scored.slice(1, 4).map((s) => ({
id: s.combo.id,
name: s.combo.name,
tradeoff: s.isFree
? "free but may have limits"
: s.score < best.score * 0.5
? "cheaper but slower"
: "similar quality, different providers",
}));
const freeAlt = scored.find((s) => s.isFree && s !== best);
const result = {
recommendedCombo: {
id: best.combo.id,
name: best.combo.name,
reason: `Best match for "${args.taskType}": preferred providers (${fitness.preferred.slice(0, 3).join(", ")})`,
},
alternatives,
freeAlternative: freeAlt ? { id: freeAlt.combo.id, name: freeAlt.combo.name } : null,
};
await logToolCall(
"omniroute_best_combo_for_task",
args,
result.recommendedCombo,
Date.now() - start,
true
);
return { content: [{ type: "text" as const, text: JSON.stringify(result, null, 2) }] };
} catch (err) {
const msg = err instanceof Error ? err.message : String(err);
await logToolCall("omniroute_best_combo_for_task", args, null, Date.now() - start, false, msg);
return { content: [{ type: "text" as const, text: `Error: ${msg}` }], isError: true };
}
}
export async function handleExplainRoute(args: { requestId: string }) {
const start = Date.now();
try {
// Query routing_decisions table via API
let decision: JsonRecord | null = null;
try {
decision = toRecord(
await apiFetch(`/api/routing/decisions/${encodeURIComponent(args.requestId)}`)
);
} catch {
// Fall back to a generic explanation
}
const result = decision
? {
requestId: args.requestId,
decision: {
comboUsed: decision.comboUsed || "default",
providerSelected: decision.providerSelected || "unknown",
modelUsed: decision.modelUsed || "unknown",
score: decision.score || 0,
factors: decision.factors || [
{ name: "health", value: 1, weight: 0.3, contribution: 0.3 },
{ name: "quota", value: 1, weight: 0.25, contribution: 0.25 },
{ name: "cost", value: 0.8, weight: 0.2, contribution: 0.16 },
{ name: "latency", value: 0.9, weight: 0.15, contribution: 0.135 },
{ name: "task_fit", value: 0.7, weight: 0.1, contribution: 0.07 },
],
fallbacksTriggered: decision.fallbacksTriggered || [],
costActual: decision.costActual || 0,
latencyActual: decision.latencyActual || 0,
},
}
: {
requestId: args.requestId,
decision: {
comboUsed: "unknown",
providerSelected: "unknown",
modelUsed: "unknown",
score: 0,
factors: [],
fallbacksTriggered: [],
costActual: 0,
latencyActual: 0,
},
note: "Routing decision not found. The /api/routing/decisions endpoint may not be implemented yet, or the requestId is invalid.",
};
await logToolCall(
"omniroute_explain_route",
args,
{ requestId: args.requestId },
Date.now() - start,
true
);
return { content: [{ type: "text" as const, text: JSON.stringify(result, null, 2) }] };
} catch (err) {
const msg = err instanceof Error ? err.message : String(err);
await logToolCall("omniroute_explain_route", args, null, Date.now() - start, false, msg);
return { content: [{ type: "text" as const, text: `Error: ${msg}` }], isError: true };
}
}
export async function handleSyncPricing(args: { sources?: string[]; dryRun?: boolean }) {
const start = Date.now();
try {
const result = toRecord(
await apiFetch("/api/pricing/sync", {
method: "POST",
body: JSON.stringify({
sources: args.sources,
dryRun: args.dryRun ?? false,
}),
})
);
await logToolCall("omniroute_sync_pricing", args, result, Date.now() - start, true);
return { content: [{ type: "text" as const, text: JSON.stringify(result, null, 2) }] };
} catch (err) {
const msg = err instanceof Error ? err.message : String(err);
await logToolCall("omniroute_sync_pricing", args, null, Date.now() - start, false, msg);
return { content: [{ type: "text" as const, text: `Error: ${msg}` }], isError: true };
}
}
export async function handleGetSessionSnapshot() {
const start = Date.now();
try {
const analytics = toRecord(
await apiFetch("/api/usage/analytics?period=session").catch(() => ({}))
);
const tokenCount = toRecord(analytics.tokenCount);
const byModel = toArrayOfRecords(analytics.byModel);
const byProvider = toArrayOfRecords(analytics.byProvider);
const result = {
sessionStart: toString(analytics.sessionStart, new Date().toISOString()),
duration: toString(analytics.duration, "unknown"),
requestCount: toNumber(analytics.requestCount, 0),
costTotal: toNumber(analytics.totalCost, 0),
tokenCount: {
prompt: toNumber(tokenCount.prompt, 0),
completion: toNumber(tokenCount.completion, 0),
},
topModels: byModel.slice(0, 5).map((model) => ({
model: toString(model.model, "unknown"),
count: toNumber(model.requests, 0),
})),
topProviders: byProvider.slice(0, 5).map((provider) => ({
provider: toString(provider.name, "unknown"),
count: toNumber(provider.requests, 0),
})),
errors: toNumber(analytics.errorCount, 0),
fallbacks: toNumber(analytics.fallbackCount, 0),
budgetGuard: activeBudgetGuard
? {
active: true,
remaining: Math.max(0, activeBudgetGuard.maxCost - activeBudgetGuard.spent),
action: activeBudgetGuard.action,
}
: null,
};
await logToolCall(
"omniroute_get_session_snapshot",
{},
{ requestCount: result.requestCount },
Date.now() - start,
true
);
return { content: [{ type: "text" as const, text: JSON.stringify(result, null, 2) }] };
} catch (err) {
const msg = err instanceof Error ? err.message : String(err);
await logToolCall("omniroute_get_session_snapshot", {}, null, Date.now() - start, false, msg);
return { content: [{ type: "text" as const, text: `Error: ${msg}` }], isError: true };
}
}
export async function handleDbHealthCheck(args: { autoRepair?: boolean }) {
const start = Date.now();
const autoRepair = args.autoRepair === true;
try {
const { runManagedDbHealthCheck } = await import("../../../src/lib/db/core.ts");
const result = runManagedDbHealthCheck({ autoRepair });
await logToolCall(
"omniroute_db_health_check",
args,
{
isHealthy: toBoolean(result.isHealthy, false),
repairedCount: toNumber(result.repairedCount, 0),
},
Date.now() - start,
true
);
return { content: [{ type: "text" as const, text: JSON.stringify(result, null, 2) }] };
} catch (err) {
const msg = err instanceof Error ? err.message : String(err);
await logToolCall("omniroute_db_health_check", args, null, Date.now() - start, false, msg);
return { content: [{ type: "text" as const, text: `Error: ${msg}` }], isError: true };
}
}
export async function handleCacheStats() {
const start = Date.now();
try {
const raw = toRecord(await apiFetch("/api/cache"));
const semanticCache = toRecord(raw.semanticCache);
const promptCache = raw.promptCache ? toRecord(raw.promptCache) : null;
const idempotency = toRecord(raw.idempotency);
const config = raw.config ? toRecord(raw.config) : null;
const result = {
semanticCache: {
memoryEntries: toNumber(semanticCache.memoryEntries, 0),
dbEntries: toNumber(semanticCache.dbEntries, 0),
hits: toNumber(semanticCache.hits, 0),
misses: toNumber(semanticCache.misses, 0),
hitRate: toString(semanticCache.hitRate, "0%"),
tokensSaved: toNumber(semanticCache.tokensSaved, 0),
},
promptCache: promptCache
? {
totalRequests: toNumber(promptCache.totalRequests, 0),
requestsWithCacheControl: toNumber(promptCache.requestsWithCacheControl, 0),
totalInputTokens: toNumber(promptCache.totalInputTokens, 0),
totalCachedTokens: toNumber(promptCache.totalCachedTokens, 0),
totalCacheCreationTokens: toNumber(promptCache.totalCacheCreationTokens, 0),
tokensSaved: toNumber(promptCache.tokensSaved, 0),
estimatedCostSaved: toNumber(promptCache.estimatedCostSaved, 0),
}
: null,
idempotency: {
activeKeys: toNumber(idempotency.activeKeys, 0),
windowMs: toNumber(idempotency.windowMs, 0),
},
config: config
? {
semanticCacheEnabled: toBoolean(config.semanticCacheEnabled, true),
}
: undefined,
};
await logToolCall("omniroute_cache_stats", {}, result, Date.now() - start, true);
return { content: [{ type: "text" as const, text: JSON.stringify(result, null, 2) }] };
} catch (err) {
const msg = err instanceof Error ? err.message : String(err);
await logToolCall("omniroute_cache_stats", {}, null, Date.now() - start, false, msg);
return { content: [{ type: "text" as const, text: `Error: ${msg}` }], isError: true };
}
}
export async function handleCacheFlush(args: { signature?: string; model?: string }) {
const start = Date.now();
try {
const params = new URLSearchParams();
let scope = "all";
if (args.signature) {
params.set("signature", args.signature);
scope = "signature";
} else if (args.model) {
params.set("model", args.model);
scope = "model";
}
const query = params.toString();
const path = query ? `/api/cache?${query}` : "/api/cache";
const raw = toRecord(
await apiFetch(path, {
method: "DELETE",
})
);
const result = {
ok: toBoolean(raw.ok, true),
invalidated: toNumber(raw.invalidated ?? raw.cleared, 0),
scope,
};
await logToolCall("omniroute_cache_flush", args, result, Date.now() - start, true);
return { content: [{ type: "text" as const, text: JSON.stringify(result, null, 2) }] };
} catch (err) {
const msg = err instanceof Error ? err.message : String(err);
await logToolCall("omniroute_cache_flush", args, null, Date.now() - start, false, msg);
return { content: [{ type: "text" as const, text: `Error: ${msg}` }], isError: true };
}
}
// ============ 1proxy Tools ============
export async function handleOneproxyFetch(
args: { protocol?: string; countryCode?: string; minQuality?: number; limit?: number } = {}
) {
const start = Date.now();
try {
const params = new URLSearchParams();
if (args.protocol) params.set("protocol", args.protocol);
if (args.countryCode) params.set("countryCode", args.countryCode);
if (args.minQuality) params.set("minQuality", String(args.minQuality));
if (args.limit) params.set("limit", String(args.limit));
const query = params.toString();
const path = query ? `/api/settings/oneproxy?${query}` : "/api/settings/oneproxy";
const raw = toRecord(await apiFetch(path));
const items = toArrayOfRecords(raw.items).map((r) => ({
id: toString(r.id, ""),
host: toString(r.host, ""),
port: toNumber(r.port, 0),
type: toString(r.type, "http"),
countryCode: typeof r.country_code === "string" ? r.country_code : null,
qualityScore: r.quality_score != null ? toNumber(r.quality_score) : null,
latencyMs: r.latency_ms != null ? toNumber(r.latency_ms) : null,
anonymity: typeof r.anonymity === "string" ? r.anonymity : null,
googleAccess: r.google_access === 1 || r.google_access === true,
status: toString(r.status, "active"),
}));
const result = { items, total: toNumber(raw.total, items.length) };
await logToolCall("omniroute_oneproxy_fetch", args, result, Date.now() - start, true);
return { content: [{ type: "text" as const, text: JSON.stringify(result, null, 2) }] };
} catch (err) {
const msg = err instanceof Error ? err.message : String(err);
await logToolCall("omniroute_oneproxy_fetch", args, null, Date.now() - start, false, msg);
return { content: [{ type: "text" as const, text: `Error: ${msg}` }], isError: true };
}
}
export async function handleOneproxyRotate(
args: { strategy?: "random" | "quality" | "sequential" } = {}
) {
const start = Date.now();
try {
const body: Record<string, unknown> = {};
if (args.strategy) body.strategy = args.strategy;
const raw = toRecord(
await apiFetch("/api/settings/oneproxy/rotate", {
method: "POST",
body: JSON.stringify(body),
})
);
const result = {
id: toString(raw.id, ""),
host: toString(raw.host, ""),
port: toNumber(raw.port, 0),
type: toString(raw.type, "http"),
countryCode: typeof raw.country_code === "string" ? raw.country_code : null,
qualityScore: raw.quality_score != null ? toNumber(raw.quality_score) : null,
latencyMs: raw.latency_ms != null ? toNumber(raw.latency_ms) : null,
};
await logToolCall("omniroute_oneproxy_rotate", args, result, Date.now() - start, true);
return { content: [{ type: "text" as const, text: JSON.stringify(result, null, 2) }] };
} catch (err) {
const msg = err instanceof Error ? err.message : String(err);
await logToolCall("omniroute_oneproxy_rotate", args, null, Date.now() - start, false, msg);
return { content: [{ type: "text" as const, text: `Error: ${msg}` }], isError: true };
}
}
export async function handleOneproxyStats(args: Record<string, never> = {}) {
const start = Date.now();
try {
const raw = toRecord(await apiFetch("/api/settings/oneproxy?action=stats"));
const statsRaw = toRecord(raw.stats);
const statusRaw = toRecord(raw.status);
const stats = {
total: toNumber(statsRaw.total, 0),
active: toNumber(statsRaw.active, 0),
avgQuality: statsRaw.avg_quality != null ? toNumber(statsRaw.avg_quality) : null,
lastValidated: typeof statsRaw.last_validated === "string" ? statsRaw.last_validated : null,
byProtocol: toArrayOfRecords(statsRaw.by_protocol || statsRaw.byProtocol).map((r) => ({
protocol: toString(r.protocol, ""),
count: toNumber(r.count, 0),
})),
byCountry: toArrayOfRecords(statsRaw.by_country || statsRaw.byCountry).map((r) => ({
countryCode: toString(r.countryCode || r.country_code, ""),
count: toNumber(r.count, 0),
})),
};
const status = {
lastSyncSuccess: toBoolean(statusRaw.last_sync_success, false),
lastSyncError:
typeof statusRaw.last_sync_error === "string" ? statusRaw.last_sync_error : null,
lastSyncAt: typeof statusRaw.last_sync_at === "string" ? statusRaw.last_sync_at : null,
lastSyncCount: toNumber(statusRaw.last_sync_count, 0),
consecutiveFailures: toNumber(statusRaw.consecutive_failures, 0),
};
const result = { stats, status };
await logToolCall("omniroute_oneproxy_stats", args, result, Date.now() - start, true);
return { content: [{ type: "text" as const, text: JSON.stringify(result, null, 2) }] };
} catch (err) {
const msg = err instanceof Error ? err.message : String(err);
await logToolCall("omniroute_oneproxy_stats", args, null, Date.now() - start, false, msg);
return { content: [{ type: "text" as const, text: `Error: ${msg}` }], isError: true };
}
}