mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-12 10:12:11 +03:00
fix(ci): clear base-red typecheck + migration collisions on release/v3.8.50
Resolve 13 typecheck:core errors (deepai executor/import, responseSanitizer cached_tokens typing, search.ts token headers, usageTracking duplicate props, modelCapabilityOverrideKey max_token, executeWebSearch null) and remove the stale duplicate 143_job_registry.sql (canonical is 146_job_registry per RENAMED_MIGRATION_COMPATIBILITY), freeing the 147 KNOWN_GAPS entry. Base-reds tracked by #9985.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import type { RegistryEntry } from "../shared";
|
||||
import type { RegistryEntry } from "../../shared";
|
||||
|
||||
export const deepaiProvider: RegistryEntry = {
|
||||
id: "deepai",
|
||||
@@ -7,6 +7,7 @@ export const deepaiProvider: RegistryEntry = {
|
||||
baseUrl: "https://api.deepai.org",
|
||||
authType: "apikey",
|
||||
authHeader: "api-key",
|
||||
executor: "default",
|
||||
models: [
|
||||
{ id: "text2img", name: "Text to Image" },
|
||||
],
|
||||
|
||||
@@ -537,7 +537,7 @@ function sanitizeResponsesUsage(usage: unknown): unknown {
|
||||
// DeepSeek native API: map flat prompt_cache_hit_tokens into input_tokens_details
|
||||
if (
|
||||
normalized.prompt_cache_hit_tokens !== undefined &&
|
||||
!normalized.input_tokens_details?.cached_tokens
|
||||
!(toRecord(normalized.input_tokens_details) ?? {}).cached_tokens
|
||||
) {
|
||||
normalized.input_tokens_details = {
|
||||
...(normalized.input_tokens_details as Record<string, unknown> || {}),
|
||||
@@ -549,7 +549,7 @@ function sanitizeResponsesUsage(usage: unknown): unknown {
|
||||
if (
|
||||
normalized.cache_read_input_tokens !== undefined &&
|
||||
normalized.cache_read_input_tokens !== 0 &&
|
||||
!normalized.input_tokens_details?.cached_tokens
|
||||
!(toRecord(normalized.input_tokens_details) ?? {}).cached_tokens
|
||||
) {
|
||||
normalized.input_tokens_details = {
|
||||
...(normalized.input_tokens_details as Record<string, unknown> || {}),
|
||||
|
||||
@@ -304,7 +304,7 @@ function buildSerperRequest(
|
||||
url: `${config.baseUrl}${endpoint}`,
|
||||
init: {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json", "X-API-Key": params.token },
|
||||
headers: { "Content-Type": "application/json", ...(params.token ? { "X-API-Key": params.token } : {}) },
|
||||
body: JSON.stringify(body),
|
||||
},
|
||||
};
|
||||
@@ -322,7 +322,7 @@ function buildBraveRequest(
|
||||
url: `${config.baseUrl}${endpoint}?${qp}`,
|
||||
init: {
|
||||
method: "GET",
|
||||
headers: { Accept: "application/json", "X-Subscription-Token": params.token },
|
||||
headers: { Accept: "application/json", ...(params.token ? { "X-Subscription-Token": params.token } : {}) },
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -348,7 +348,7 @@ function buildExaRequest(
|
||||
url: config.baseUrl,
|
||||
init: {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json", "x-api-key": params.token },
|
||||
headers: { "Content-Type": "application/json", ...(params.token ? { "x-api-key": params.token } : {}) },
|
||||
body: JSON.stringify(body),
|
||||
},
|
||||
};
|
||||
|
||||
@@ -665,8 +665,6 @@ export function extractUsage(chunk) {
|
||||
chunk.usage.reasoning_tokens,
|
||||
// xAI's exact provider-reported cost (port of decolua/9router#2453, capability A).
|
||||
cost_in_usd_ticks: chunk.usage.cost_in_usd_ticks,
|
||||
cache_read_input_tokens: chunk.usage.cache_read_input_tokens,
|
||||
cache_creation_input_tokens: chunk.usage.cache_creation_input_tokens,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ export const KNOWN_DUPLICATE_VERSIONS = new Set([
|
||||
// O stale-enforcement exige que cada reserva seja removida quando os arquivos
|
||||
// correspondentes aterrissarem na release.
|
||||
// ---------------------------------------------------------------------------
|
||||
export const KNOWN_GAPS = new Set(["026", "055", "121", "144", "145", "147", "148", "149"]); // 121: número queimado no ciclo v3.8.47 — 122 (#6909) mergeou antes e 121 nunca aterrissou (validação e2e 2026-07-12)
|
||||
export const KNOWN_GAPS = new Set(["026", "055", "121", "144", "145", "148", "149"]); // 121: número queimado no ciclo v3.8.47 — 122 (#6909) mergeou antes e 121 nunca aterrissou (validação e2e 2026-07-12)
|
||||
|
||||
function pad3(n) {
|
||||
return String(n).padStart(3, "0");
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
-- Migration 139: generic job registry (jobs + job_runs tables)
|
||||
-- Job registry (#8848): centralized periodic-job scheduling + run history.
|
||||
--
|
||||
-- jobs: one row per registered job (interval or cron), with env-flag gating
|
||||
-- job_runs: one row per execution (running/success/failure), pruned by count + age
|
||||
|
||||
CREATE TABLE IF NOT EXISTS jobs (
|
||||
id TEXT PRIMARY KEY,
|
||||
type TEXT NOT NULL DEFAULT 'interval' CHECK(type IN ('interval', 'cron')),
|
||||
cron TEXT, -- cron expression (type='cron'); NULL for interval jobs
|
||||
interval_ms INTEGER, -- interval in ms (type='interval'); NULL for cron jobs
|
||||
enabled INTEGER NOT NULL DEFAULT 1, -- 0=disabled, 1=enabled
|
||||
env_flag TEXT, -- env var name (boolean gate), e.g. 'OMNIROUTE_WARMUP_ENABLED'; NULL = no gate
|
||||
config TEXT NOT NULL DEFAULT '{}', -- JSON config (concurrency, timezone, envDefault, ...)
|
||||
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS job_runs (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
job_id TEXT NOT NULL REFERENCES jobs(id) ON DELETE CASCADE,
|
||||
started_at TEXT NOT NULL, -- ISO-8601, written explicitly by recordRun (no DB default)
|
||||
finished_at TEXT, -- ISO-8601; NULL while running
|
||||
status TEXT NOT NULL DEFAULT 'running', -- 'running' | 'success' | 'failure'
|
||||
error_message TEXT, -- sanitized error message (no stack trace)
|
||||
records_affected INTEGER DEFAULT 0, -- job-specific meaning (see below)
|
||||
duration_ms INTEGER, -- execution duration in ms
|
||||
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_jr_job_id ON job_runs(job_id, started_at DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_jr_started_at ON job_runs(started_at);
|
||||
|
||||
-- Built-in job registration (idempotent - INSERT OR IGNORE).
|
||||
-- env_flag = NULL means "no registry-level boolean gate"; per-job disable semantics
|
||||
-- live inside the handler itself (see token_health_check wrapper).
|
||||
-- 'warmup' is seeded disabled because its handler is not part of this change.
|
||||
-- startAll() filters on enabled before it looks for a handler, so a disabled row
|
||||
-- stays quiet instead of warning on every boot; the change that brings the warmup
|
||||
-- handler flips it on.
|
||||
INSERT OR IGNORE INTO jobs (id, type, cron, interval_ms, enabled, env_flag, config) VALUES
|
||||
('budget_reset', 'interval', NULL, 600000, 1, NULL, '{}'),
|
||||
('warmup', 'cron', '0 7 * * *', NULL, 0, 'OMNIROUTE_WARMUP_ENABLED', '{"timezone":"America/Los_Angeles","envDefault":false}'),
|
||||
('token_health_check', 'interval', NULL, 60000, 1, NULL, '{}');
|
||||
|
||||
-- records_affected semantics:
|
||||
-- budget_reset = number of budget records reset (UPDATE ... SET budget_used=0 row count)
|
||||
-- warmup = number of connections attempted for warmup
|
||||
-- token_health_check = number of connections swept by the health check
|
||||
@@ -1,7 +1,7 @@
|
||||
import { getDbInstance } from "./core";
|
||||
import { invalidateDbCache } from "./readCache";
|
||||
|
||||
export type ModelCapabilityOverrideKey = "max_input_tokens" | "max_output_tokens";
|
||||
export type ModelCapabilityOverrideKey = "max_input_tokens" | "max_output_tokens" | "max_token";
|
||||
|
||||
export interface ModelCapabilityOverride {
|
||||
provider: string;
|
||||
@@ -21,7 +21,7 @@ interface OverrideRow {
|
||||
}
|
||||
|
||||
function isSupportedKey(value: unknown): value is ModelCapabilityOverrideKey {
|
||||
return value === "max_input_tokens" || value === "max_output_tokens";
|
||||
return value === "max_input_tokens" || value === "max_output_tokens" || value === "max_token";
|
||||
}
|
||||
|
||||
function isPositiveInteger(value: unknown): value is number {
|
||||
|
||||
@@ -222,7 +222,7 @@ export async function executeWebSearch(
|
||||
.filter((provider) => supportsSearchType(provider, searchType))
|
||||
.sort((a, b) => a.costPerQuery - b.costPerQuery)
|
||||
.map((provider) => provider.id)
|
||||
.filter((providerId) => providerId !== providerConfig.id);
|
||||
.filter((providerId) => providerId !== providerConfig!.id);
|
||||
|
||||
for (const providerId of otherIds) {
|
||||
const creds = await resolveSearchCredentials(providerId);
|
||||
|
||||
Reference in New Issue
Block a user