mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-22 07:02:16 +03:00
⭐5 — Cursor PKCE login com Bearer quota, auto router e empty-turn errors. Feature completa e testada (11 arquivos de teste, 133 testes focados, todos verdes).
**Validação (worktree combinado `.claude/worktrees/fix-9909`, board sobre `origin/release/v3.8.50`):**
- 3 conflitos reais resolvidos: `config/quality/eslint-suppressions.json` (aditivo), `open-sse/config/providers/registry/cursor/index.ts` (dedup de 208 entradas de catálogo, 0 IDs duplicados verificado), `open-sse/executors/cursor.ts` (imports aditivos).
- `npm run typecheck:core`: limpo.
- `check-changelog-integrity`, `check-file-size`, `check-complexity` (2615/2774), `check-cognitive-complexity` (1175/1223), `check-dead-code` (410/416): todos OK.
- `check-public-creds`: 1 entrada obsoleta pré-existente na allowlist (`copilot-m365-web.ts:330`), já presente no tip da release — não é desta PR.
- `npm run lint`: 0 errors (5 warnings pré-existentes).
- Testes focados (`cursor-agent-cli-version`, `cursor-available-models`, `cursor-catalog-combo-compat`, `cursor-errors-classify`, `cursor-login-pkce`, `cursor-model-effort-suffix-7289`, `cursor-streaming`, `cursor-token-extractor`, `cursor-token-refresh-wiring`, `cursor-usage-fetcher`, `empty-stream-no-content-8649`): 133/133 verdes.
- Corrigido durante a validação: 1 teste novo da própria PR (`cursor-model-effort-suffix-7289.test.ts`, "splits effort off legacy grok- ids") colidia com `CURSOR_MODEL_ALIASES` já mesclado na release (mapeia `grok-4.5-high` → `cursor-grok-4.5-high` antes do fallback legado rodar); ajustado para usar um id não-aliasado (`grok-3-high`) que de fato exercita o fallback — commit `68b58ed`.
Obrigado pela contribuição, @yansigit — feature robusta com boa cobertura de testes.
102 lines
3.8 KiB
TypeScript
102 lines
3.8 KiB
TypeScript
import { describe, it } from "node:test";
|
|
import assert from "node:assert/strict";
|
|
import {
|
|
ensureCursorAutoCatalogEntry,
|
|
normalizeCursorAvailableModelsPayload,
|
|
} from "../../src/lib/providerModels/cursorAvailableModels.ts";
|
|
import { resolveRequestedModel } from "../../open-sse/utils/cursorAgentProtobuf.ts";
|
|
|
|
describe("normalizeCursorAvailableModelsPayload", () => {
|
|
it("extracts models from models[] with name ids", () => {
|
|
const models = normalizeCursorAvailableModelsPayload({
|
|
models: [
|
|
{ name: "claude-opus-5-high", displayName: "Opus 5" },
|
|
{ name: "gpt-5.6-sol-high", displayName: "GPT-5.6 Sol" },
|
|
{ name: "disabled-model", disabled: true },
|
|
],
|
|
});
|
|
assert.equal(models[0].id, "auto");
|
|
assert.ok(models.some((m) => m.id === "claude-opus-5-high"));
|
|
assert.ok(models.some((m) => m.id === "gpt-5.6-sol-high"));
|
|
assert.ok(models.some((m) => m.id === "auto-cost"));
|
|
assert.equal(models.find((m) => m.id === "claude-opus-5-high")?.name, "Opus 5");
|
|
assert.equal(models.find((m) => m.id === "claude-opus-5-high")?.owned_by, "cursor");
|
|
assert.equal(
|
|
models.some((m) => m.id === "disabled-model"),
|
|
false
|
|
);
|
|
});
|
|
|
|
it("accepts string arrays and skips empties", () => {
|
|
const models = normalizeCursorAvailableModelsPayload({
|
|
availableModels: ["auto", "composer-2.5", "auto", ""],
|
|
});
|
|
assert.equal(models[0].id, "auto");
|
|
assert.ok(models.some((m) => m.id === "composer-2.5"));
|
|
assert.ok(models.some((m) => m.id === "auto-balance"));
|
|
// Only one auto entry despite duplicate in payload
|
|
assert.equal(models.filter((m) => m.id === "auto").length, 1);
|
|
});
|
|
|
|
it("aliases default to auto and keeps default", () => {
|
|
const models = normalizeCursorAvailableModelsPayload({
|
|
models: [{ name: "default", displayName: "Auto" }, { name: "composer-2.5" }],
|
|
});
|
|
assert.equal(models[0].id, "auto");
|
|
assert.equal(models[0].name, "Auto");
|
|
assert.ok(models.some((m) => m.id === "default"));
|
|
assert.ok(models.some((m) => m.id === "composer-2.5"));
|
|
});
|
|
|
|
it("injects auto when payload has neither auto nor default", () => {
|
|
const models = normalizeCursorAvailableModelsPayload({
|
|
models: [{ name: "composer-2.5" }],
|
|
});
|
|
assert.equal(models[0].id, "auto");
|
|
assert.match(models[0].name, /Auto/i);
|
|
});
|
|
|
|
it("injects auto into an empty usable list", () => {
|
|
const models = normalizeCursorAvailableModelsPayload({ models: [] });
|
|
assert.deepEqual(
|
|
models.map((m) => m.id),
|
|
["auto", "auto-cost", "auto-balance", "auto-intelligence"]
|
|
);
|
|
});
|
|
|
|
it("injects auto router variants alongside existing models", () => {
|
|
const models = normalizeCursorAvailableModelsPayload({
|
|
models: [{ name: "composer-2.5" }],
|
|
});
|
|
for (const id of ["auto", "auto-cost", "auto-balance", "auto-intelligence", "composer-2.5"]) {
|
|
assert.ok(
|
|
models.some((m) => m.id === id),
|
|
`missing ${id}`
|
|
);
|
|
}
|
|
});
|
|
});
|
|
|
|
describe("ensureCursorAutoCatalogEntry + resolveRequestedModel", () => {
|
|
it("catalog auto stays aligned with wire default", () => {
|
|
const models = ensureCursorAutoCatalogEntry([]);
|
|
assert.equal(models[0].id, "auto");
|
|
assert.deepEqual(resolveRequestedModel("auto"), { modelId: "default", parameters: [] });
|
|
});
|
|
|
|
it("auto-cost/balance/intelligence map to default + optimization parameter", () => {
|
|
assert.deepEqual(resolveRequestedModel("auto-cost"), {
|
|
modelId: "default",
|
|
parameters: [{ id: "optimization", value: "cost" }],
|
|
});
|
|
assert.deepEqual(resolveRequestedModel("auto-balance"), {
|
|
modelId: "default",
|
|
parameters: [{ id: "optimization", value: "balance" }],
|
|
});
|
|
assert.deepEqual(resolveRequestedModel("auto-intelligence"), {
|
|
modelId: "default",
|
|
parameters: [{ id: "optimization", value: "intelligence" }],
|
|
});
|
|
});
|
|
});
|