mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-10 17:22:17 +03:00
Merge remote-tracking branch 'origin/release/v3.8.50' into test/9178-opencode-plugin-bare-key-suite
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"_rebaseline_2026_08_08_migration_135_collision": "fix(db): resolve migration version 135 numbering collision — #9449's 135_connection_runtime_state.sql and #8908's 135_migrate_model_capability_max_token.sql both claimed version 135 (#9449 branched before #8908 merged and never got renumbered before landing on release/v3.8.50), which threw 'Migration version collision detected' the moment ANY code touched the database — a fresh install/deploy from this tip cannot even boot. Renumbered the later-landing file to 140 (next free slot) and added the matching isSchemaAlreadyApplied('140') retroactive guard, matching the established pattern already used for the prior 135/136 -> 137/138 renumber in the same file. Own growth: src/lib/db/migrationRunner.ts 1084->1094 (+10, the new case block) — irreducible, matches the existing per-case guard pattern exactly. Covered by tests/unit/migration-135-numbering-collision.test.ts (2/2), confirmed failing (reproducing the exact live crash) against the pre-fix colliding filenames, passing after.",
|
||||
"_rebaseline_2026_08_02_9259_rolling_rpm": "PR #9259 (issue #8733) own growth: open-sse/services/rateLimitManager.ts baseline 1060->1167 (+107; final source 1153). The existing withRateLimit chokepoint now composes process-local rolling RPM leases with Bottleneck admission, releases pre-dispatch leases on queue timeout/abort/connection disable, preserves caller abort reasons, and wires 429/header state into the extracted rollingRpmGate.ts. The remaining growth is irreducible lifecycle wiring at the dispatch boundary plus the real watchdog test hooks needed to verify queued-wedge recovery; moving it further would obscure lease ownership and Bottleneck cleanup. Covered by the focused rate-limit manager/sliding-window suite (33/33); distributed multi-instance coordination remains explicitly out of scope.",
|
||||
"_rebaseline_2026_07_24_8470_hyperagent_sticky_thread": "PR #8470 (artickc, fix/hyperagent-tool-loop-thread-sticky) own growth: open-sse/executors/hyperagent.ts 936->1025 (wc -l; check-file-size.mjs counts via split(\"\\n\").length so the gate sees 937->1026, +89, crosses the 1000 cap). Fixes a real bug where a reverse-conversion proxy (text-Intent/JSON to Claude Code native tool_calls) rewrites assistant messages between agentic tool-loop turns, breaking HyperAgent’s conversation-prefix fingerprint and cold-starting the thread mid tool-loop. Adds Anthropic tool_use/tool_result flattening to extractMessageText() plus a new rootUserFingerprint()/root-key lookup tier in resolveHyperAgentThreadBinding()/storeHyperAgentThreadAfterTurn() so the thread stays sticky across the tool loop. Cohesive additions inside the existing single-file executor; not extractable without splitting the executor mid-request-flow. Covered by tests/unit/executor-hyperagent.test.ts (19/19, +5 new cases for tool_result/tool_use flattening + root-key stickiness). Pre-merge review flagged a cross-conversation root-key collision risk (tracked in the PR’s own mandatory pre-merge checklist, not yet addressed) — unrelated to this file-size ratchet, tracked separately by /fix-prs.",
|
||||
"_rebaseline_2026_07_25_8494_capability_filter_fail_closed": "PR #8494 (fix/capability-filters-fail-closed, #8488) own growth: open-sse/services/combo.ts 3640->3693 (+53) adds a fail-closed guard after filterTargetsByRequestCompatibility() — when every eligible target is excluded by request-capability filtering (vision/tools/etc) instead of quota/health, the combo now returns an explicit `capability_mismatch` 400 (describeCapabilityFilterExhaustion, imported from combo/comboStructure.ts) rather than silently falling through to a generic no-targets error, plus a `compatFilterFailOpen` escape hatch (combo config OR settings) mirrored at both the main/auto and round-robin call sites for symmetry. combo/comboStructure.ts (previously under cap, un-frozen) grows 794->918 (+124) — new home for describeCapabilityFilterExhaustion + providerSupportsEmulatedToolCalling (#5240 emulated tool-calling exemption so fail-closed does not regress prompt-emulation-only combos like all-chatgpt-web). Irreducible orchestration wiring at the existing filter chokepoint (same precedent as #7301's universal-cooldown-retry generalization). Companion test tests/unit/combo-routing-engine.test.ts 3409->3449 (+40, fail-closed/fail-open coverage across both call sites) also rebaselined. Covered by tests/unit/8488-capability-filter-fail-closed.test.ts (new) + 95/95 passing across both files. Structural shrink of combo.ts tracked in #3501.",
|
||||
@@ -268,7 +269,7 @@
|
||||
"src/lib/tokenHealthCheck.ts": 1021,
|
||||
"src/lib/db/apiKeys.ts": 1529,
|
||||
"src/lib/db/core.ts": 1637,
|
||||
"src/lib/db/migrationRunner.ts": 1084,
|
||||
"src/lib/db/migrationRunner.ts": 1094,
|
||||
"src/lib/db/models.ts": 1097,
|
||||
"src/lib/db/providers.ts": 1034,
|
||||
"src/lib/memory/retrieval.ts": 1073,
|
||||
|
||||
@@ -472,6 +472,16 @@ function isSchemaAlreadyApplied(
|
||||
return hasColumn(db, "version_manager", "auto_restart_adopted");
|
||||
case "138":
|
||||
return hasColumn(db, "upstream_proxy_config", "fallback_backend");
|
||||
case "140":
|
||||
// Retroactive guard for the connection_runtime_state migration renumbered
|
||||
// 135 -> 140 (#9449 landed onto the slot already taken by #8908's
|
||||
// 135_migrate_model_capability_max_token.sql — the same recurring
|
||||
// numbering-race class as the 135/136 -> 137/138 renumber above). A DB
|
||||
// that already ran this under the old 135 number has the table, and a
|
||||
// bare CREATE TABLE re-run would otherwise just no-op (IF NOT EXISTS)
|
||||
// but still burn a version-tracking slot mismatch — guard it the same
|
||||
// way as the other renumbers for consistency.
|
||||
return hasTable(db, "connection_runtime_state");
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
67
tests/unit/migration-135-numbering-collision.test.ts
Normal file
67
tests/unit/migration-135-numbering-collision.test.ts
Normal file
@@ -0,0 +1,67 @@
|
||||
/**
|
||||
* Regression test for a migration version-numbering collision: two files,
|
||||
* 135_connection_runtime_state.sql (#9449, landed 2026-08-07) and
|
||||
* 135_migrate_model_capability_max_token.sql (#8908, landed 2026-08-05),
|
||||
* both claimed version "135" — #9449 branched before #8908 merged and never
|
||||
* got renumbered before landing on release/v3.8.50.
|
||||
*
|
||||
* This is not a cosmetic issue: `getMigrationFiles()` throws
|
||||
* "Migration version collision detected" the moment ANY code path first
|
||||
* touches the database (getDbInstance() -> runMigrations()), which means a
|
||||
* completely fresh install/deploy from this branch cannot even boot —
|
||||
* confirmed live against a freshly built container.
|
||||
*
|
||||
* Fix: renumbered the later-landing file to 140 (the next free slot) and
|
||||
* added the matching isSchemaAlreadyApplied("140") retroactive guard
|
||||
* (migrationRunner.ts), matching the established pattern already used for
|
||||
* the prior 135/136 -> 137/138 renumber in the same file.
|
||||
*/
|
||||
import { test, before, after } from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
import fs from "node:fs";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
|
||||
const TEST_DATA_DIR = fs.mkdtempSync(path.join(os.tmpdir(), "omniroute-migration-135-"));
|
||||
const originalDataDir = process.env.DATA_DIR;
|
||||
process.env.DATA_DIR = TEST_DATA_DIR;
|
||||
|
||||
let core: typeof import("../../src/lib/db/core.ts");
|
||||
|
||||
before(async () => {
|
||||
core = await import("../../src/lib/db/core.ts");
|
||||
});
|
||||
|
||||
after(() => {
|
||||
core.resetDbInstance();
|
||||
fs.rmSync(TEST_DATA_DIR, { recursive: true, force: true });
|
||||
if (originalDataDir === undefined) delete process.env.DATA_DIR;
|
||||
else process.env.DATA_DIR = originalDataDir;
|
||||
});
|
||||
|
||||
test("a fresh install applies all real on-disk migrations without a version collision", () => {
|
||||
// getDbInstance() runs every migration file under src/lib/db/migrations/
|
||||
// against a brand-new, empty SQLite file — the exact scenario a fresh
|
||||
// deploy hits. Before the fix this threw synchronously here.
|
||||
assert.doesNotThrow(() => core.getDbInstance());
|
||||
});
|
||||
|
||||
test("both formerly-135 migrations' tables exist after a fresh install", () => {
|
||||
const db = core.getDbInstance();
|
||||
const tableNames = (
|
||||
db.prepare("SELECT name FROM sqlite_master WHERE type = 'table'").all() as Array<{
|
||||
name: string;
|
||||
}>
|
||||
).map((row) => row.name);
|
||||
|
||||
// From 135_connection_runtime_state.sql (renumbered to 140).
|
||||
assert.ok(
|
||||
tableNames.includes("connection_runtime_state"),
|
||||
"connection_runtime_state table must exist"
|
||||
);
|
||||
// From 135_migrate_model_capability_max_token.sql (kept at 135) — this
|
||||
// migration only mutates existing model_capabilities rows, so its
|
||||
// observable effect is that the migration completed, not a new table;
|
||||
// provider_connections already exists as its target table.
|
||||
assert.ok(tableNames.includes("provider_connections"), "sanity: base schema applied");
|
||||
});
|
||||
Reference in New Issue
Block a user