mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-07-26 09:52:11 +03:00
fix(types): restore clean typecheck:core for v3.8.18 release gate
- getPendingRequests() typed to real shape (was widened to object) → fixes unknown 'count' in the unified-requests view (#3401) - streamChunks log payload cast to its declared type (callLogs.ts) - preScreenTargets aligned to canonical IsModelAvailable signature (#3169), Promise.resolve-normalized so .catch never hits a bare boolean All 5 gates green: lint(0 err) + typecheck:core + cycles + docs-all + unit + vitest(146).
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
|
||||
- **fix(executor):** Llama / OpenAI-compat base URL normalization — a `baseURL` without a path (e.g. `llama.example.foo`) or with a non-`/v1` path (e.g. `bar.example.com/foo`) now correctly gets `/v1/chat/completions` appended, fixing the 404 on message sends while `GET /model` still worked. ([#3519](https://github.com/diegosouzapw/OmniRoute/pull/3519) — thanks @hartmark)
|
||||
- **fix(sse):** empty-choices chunks without usage are dropped instead of injecting retry text — a streamed chunk carrying an empty `choices` array and no `usage` is now silently skipped rather than emitting placeholder retry text into the stream, eliminating spurious content for clients that send such keepalive-style frames. ([#3513](https://github.com/diegosouzapw/OmniRoute/pull/3513) — thanks @diegosouzapw)
|
||||
- **fix(types):** restored a clean `typecheck:core` — typed `getPendingRequests()` to its real shape (`Record<string, Record<string, number>>`) so the unified-requests view (#3401) no longer treats pending counts as `unknown`, cast the `streamChunks` log payload to its declared type, and aligned `preScreenTargets` (#3169) to the canonical `IsModelAvailable` signature (sync-or-async, normalized via `Promise.resolve`). (thanks @diegosouzapw)
|
||||
- **fix(opencode-plugin):** repaired the corrupted `index.ts` that broke the npm `publish-opencode-plugin` build (introduced by the #3435 branch) — removed two duplicated code blocks (apiFormat + debug-logging), dropped the local `normaliseFreeLabel` superseded by the `naming.ts` extraction, fixed an undefined `sdkBaseURL` reference, declared the missing `startupDebug` / `logLevel` feature-schema fields, and fixed `shortProviderLabel` dropping the prefix on a long displayName with no alias. Plugin now builds (DTS clean) with all 254 tests green. ([#3435](https://github.com/diegosouzapw/OmniRoute/pull/3435) — thanks @diegosouzapw)
|
||||
- **fix(catalog):** Codex CLI model-catalog refresh no longer errors — `GET /v1/models` now returns a top-level `models: []` array for Codex clients (detected via the `originator` / `user-agent` = `codex_*` headers it sends on `GET /v1/models?client_version=...`), so `codex_models_manager` stops failing to decode the OpenAI-standard response and no longer logs `failed to refresh available models` on every startup. The array is intentionally empty: Codex replaces its built-in per-model agent prompt (`base_instructions`, ~21k chars) with whatever a populated entry carries for the selected model, so emitting our catalog would break Codex's agent behaviour — an empty list keeps Codex on its built-in model info (same inference as before, minus the error). Non-Codex OpenAI clients receive the unchanged `{object,data}` response. ([#3481](https://github.com/diegosouzapw/OmniRoute/pull/3481) — thanks @diegosouzapw)
|
||||
- **fix(provider):** Cursor's Responses-API-shaped bodies on `/chat/completions` are detected and handled — a body with `input` but no `messages` is now classified as `openai-responses` (instead of forcing `openai` and building from undefined `messages` → upstream 400); standard OpenAI clients are unaffected by the `messages===undefined` guard. ([#3490](https://github.com/diegosouzapw/OmniRoute/pull/3490) — thanks @borodulin)
|
||||
@@ -30,6 +31,10 @@
|
||||
- **feat(docs):** doc-accuracy gate — new `npm run check:fabricated-docs` (`scripts/check/check-fabricated-docs.mjs`) indexes the codebase (api routes, env vars, CLI commands) and flags API-path/env-var/CLI/hook/file-ref claims in `docs/**` + `AGENTS.md` that don't exist in source (soft-fail by default, `--strict` for CI; wired into `check:docs-all`). Also refreshes the AGENTS.md live counts against source. ([#3510](https://github.com/diegosouzapw/OmniRoute/pull/3510) — thanks @oyi77)
|
||||
- **chore:** ignore local quality reports and prompt artifacts (`quality-metrics.json`, `PLANO-/RELATORIO-QUALITY-GATES.md`, stray prompt `.txt` files) so they no longer surface in `git status`. (thanks @diegosouzapw)
|
||||
|
||||
### 🔒 Security
|
||||
|
||||
- **fix(opencode-plugin):** bounded the regex quantifiers in `normaliseFreeLabel` to close a polynomial-ReDoS (CodeQL `js/polynomial-redos`) — an unbounded `\s*` before an anchored `\s*$` allowed O(n²) backtracking on attacker-influenced provider/model display names; bounded to `{0,8}`/`{1,8}`. (thanks @diegosouzapw)
|
||||
|
||||
---
|
||||
|
||||
## [3.8.17] — 2026-06-09
|
||||
|
||||
@@ -1839,7 +1839,7 @@ type PreScreenResult = { profile: ProviderProfile | null; available: boolean };
|
||||
|
||||
export async function preScreenTargets(
|
||||
targets: ResolvedComboTarget[],
|
||||
isModelAvailable?: ((model: string, target: ResolvedComboTarget) => Promise<boolean>) | null
|
||||
isModelAvailable?: IsModelAvailable | null
|
||||
): Promise<Map<string, PreScreenResult>> {
|
||||
if (targets.length === 0) {
|
||||
return new Map();
|
||||
@@ -1858,7 +1858,11 @@ export async function preScreenTargets(
|
||||
|
||||
let available = true;
|
||||
if (isModelAvailable) {
|
||||
available = await isModelAvailable(target.modelStr, target).catch(() => true);
|
||||
// IsModelAvailable may return a sync boolean or a Promise; Promise.resolve
|
||||
// normalizes both so the .catch() never runs against a bare boolean.
|
||||
available = await Promise.resolve(isModelAvailable(target.modelStr, target)).catch(
|
||||
() => true
|
||||
);
|
||||
}
|
||||
return { key: target.executionKey, result: { profile, available } };
|
||||
}
|
||||
|
||||
@@ -181,7 +181,9 @@ function protectPipelinePayloads(payloads: unknown): RequestPipelinePayloads | n
|
||||
)
|
||||
);
|
||||
if (Object.keys(compacted).length > 0) {
|
||||
protectedPayloads.streamChunks = protectPayloadForLog(compacted);
|
||||
protectedPayloads.streamChunks = protectPayloadForLog(
|
||||
compacted
|
||||
) as RequestPipelinePayloads["streamChunks"];
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -441,9 +441,12 @@ export function updatePendingRequestStreamChunks(
|
||||
|
||||
/**
|
||||
* Get the pending requests state (for usageStats).
|
||||
* @returns {{ byModel: Object, byAccount: Object }}
|
||||
* @returns {{ byModel: Record<string, number>, byAccount: Record<string, Record<string, number>> }}
|
||||
*/
|
||||
export function getPendingRequests(): { byModel: object; byAccount: object } {
|
||||
export function getPendingRequests(): {
|
||||
byModel: Record<string, number>;
|
||||
byAccount: Record<string, Record<string, number>>;
|
||||
} {
|
||||
return pendingRequests;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user