Skip to content

fix(cli): recognize {connections} envelope from /api/providers - #10491

Merged
diegosouzapw merged 2 commits into
cheaper-inference:release/v3.8.50from
hartmark:fix/cli-providers-connections-envelope
Aug 18, 2026
Merged

diegosouzapw merged 2 commits into
cheaper-inference:release/v3.8.50from
hartmark:fix/cli-providers-connections-envelope

Conversation

@hartmark

Copy link
Copy Markdown
Contributor

What Problem This Solves

omniroute test --all-providers and omniroute oauth providers both crash with (data.providers ?? data.items ?? data).filter is not a function on every invocation.

Why This Change Was Made

GET /api/providers returns {connections, total} (src/app/api/providers/route.ts:78), but both CLI call sites parsed the response as data.providers ?? data.items ?? data — since none of those keys exist, data itself (a plain object, not an array) falls through, and .filter throws.

bin/cli/commands/keys.mjs:222 already has the correct fallback chain (data.keys || data.connections || data.items || data); this applies the same connections field to the two remaining call sites that hit the same endpoint.

User Impact

omniroute test --all-providers and omniroute oauth providers go from a hard crash to actually working.

Evidence

Reproduced live against a running instance:

$ omniroute test --all-providers --json
✖ (data.providers ?? data.items ?? data).filter is not a function
$ curl -s "$BASE/api/providers?limit=200" -H "Authorization: Bearer $KEY" | python3 -c "import json,sys; print(list(json.load(sys.stdin).keys()))"
['connections', 'total']

After the fix, omniroute test --all-providers --json correctly enumerates configured connections instead of crashing.

GET /api/providers returns {connections, total} (src/app/api/providers/
route.ts:78), but `omniroute test --all-providers` and `omniroute oauth
providers` both parsed the response as `data.providers ?? data.items ??
data` -- an object, not an array -- so `.filter` threw
"(data.providers ?? data.items ?? data).filter is not a function" on
every call. keys.mjs already had the correct fallback chain
(`data.keys || data.connections || data.items || data`); apply the same
`connections` field to both remaining call sites.
@hartmark
hartmark requested a review from diegosouzapw as a code owner August 15, 2026 18:13
Add regression coverage for both CLI consumers of the /api/providers connections envelope.

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
@diegosouzapw

Copy link
Copy Markdown
Collaborator

A correção de produção está correta: GET /api/providers retorna {connections, total}, e o probe do head confirma que ambos os filtros passam a operar sobre esse envelope. Contudo, o PR altera dois caminhos CLI e não adiciona testes de regressão para {connections}; o teste OAuth existente cobre apenas {providers}, e não há cobertura dedicada para --all-providers. Adicione testes focados antes do merge para cumprir as Hard Rules #8/#18 e evitar a reintrodução do crash.

@hartmark

Copy link
Copy Markdown
Contributor Author

Focused regression tests for both CLI consumers of the {connections} envelope are already on this branch at the current head (6dbd5b798):

  • tests/unit/cli-oauth-commands.test.ts: runOAuthStatus consumes the connections envelope
  • tests/unit/cli-expanded-commands.test.ts: test-provider --all-providers consumes the connections envelope

Both assert the CLI correctly reads {connections} (not just {providers}) for runOAuthStatus and --all-providers respectively. Should be good to re-check.

@diegosouzapw
diegosouzapw merged commit 02a9870 into cheaper-inference:release/v3.8.50 Aug 18, 2026
5 checks passed
diegosouzapw pushed a commit that referenced this pull request Aug 19, 2026
…pool and the ESLint gate (#10726)

* fix(tests): drain the auto/glm base-red left by the Cloudflare Playground backend

provider-family-combos asserted a fixed provider list for auto/glm and started
failing on release/v3.8.50 once the Cloudflare AI Playground no-auth backend
landed: its registry advertises zai-org/glm-5.2 and zai-org/glm-4.7-flash, so the
virtual combo legitimately spans it.

The test already documents the rule it is failing on — a no-auth backend that
genuinely serves a family model IS a member of the family pool — and carries that
justification for auggie, devin-cli-agentic and zcode. Add cloudflare-playground
to the expectation with the same kind of source-cited note.

* fix(tests): green the ESLint gate left red by two untracked any casts

lint:json --max-warnings 0 failed on release/v3.8.50 because the suppression
counts drifted behind the tree: cli-oauth-commands carried 20 no-explicit-any
violations against a registered 18 (#10491 added two Commander-mock casts) and
executor-gitlab carried 5 against a registered 4 (#10499 added one).

The GitLab test casts are fixable, so they are fixed rather than suppressed: all
five now read the translated payload through a declared GitLabResponseBody
instead of any, and the file leaves the suppression list entirely.

The CLI OAuth casts target bin/cli/commands/oauth.mjs, which ships no types, so
the Commander mock has nothing to cast to; that entry only gets its count
corrected to the 20 already in the tree.
diegosouzapw added a commit that referenced this pull request Aug 23, 2026
…1236) (#11263)

Residuals of #11236 after #10371/#10491 landed on the tip:

- Dist-fold residuals (bugs 2+3): managedBinaryName() (binaryManager),
  resolveSpawnArgs() (installers/cliproxy) and the per-OS memory probes in
  getProcessInfo() (processManager) still read the process.platform literal,
  which the Linux build of the published artifact constant-folds (precedent:
  b43a212 / #10244). Converted to call-time os.platform() reads, matching
  the module's documented anti-fold pattern. Test-side process.platform uses
  are not bundled and stay.
- Fold guard: new tests/unit/windows-platform-fold-guard-11236.test.ts pins
  zero out-of-comment process.platform occurrences in the four artifact
  runtime files, with a comment-stripping tokenizer plus mutation self-checks.
- Bug 6 (pid null on Windows): portProbe.resolvePortPid() only probed
  lsof/ss/net-tools netstat. Added a netstat -ano probe with a dedicated
  LISTENING-row parser (parseWindowsNetstatPid) as the last fallback; Unix
  probes unchanged, and the Windows parser never matches Unix rows (LISTEN vs
  LISTENING). Also converted the darwin args branch in the same array to
  os.platform() (same fold class, same hunk).
- Bug 5 hardening: runOAuthStatus coerces an out-of-contract 200 payload to
  an empty list with a sanitized stderr warning instead of crashing on
  .filter over a non-array.

TDD: guard test, parser tests and the oauth hardening test all failed RED
before the fix and pass GREEN after; sibling suites (binaryManager,
processManager, portProbePid, cli-oauth-commands, installers,
ServiceSupervisor, version-manager) green. The 6877 spawn-args test's win32
mock moved from defineProperty(process.platform) to
mock.method(os, "platform") to match the new runtime read — assertion
unchanged.

Co-authored-by: Xiangzhe <bakryun0718@proton.me>
muhamadgalihsaputra pushed a commit to niyatna/NiyatnaRoute that referenced this pull request Sep 27, 2026
…er-inference#10491)

* fix(cli): recognize {connections} envelope from /api/providers

GET /api/providers returns {connections, total} (src/app/api/providers/
route.ts:78), but `omniroute test --all-providers` and `omniroute oauth
providers` both parsed the response as `data.providers ?? data.items ??
data` -- an object, not an array -- so `.filter` threw
"(data.providers ?? data.items ?? data).filter is not a function" on
every call. keys.mjs already had the correct fallback chain
(`data.keys || data.connections || data.items || data`); apply the same
`connections` field to both remaining call sites.

* test(cli): cover provider connections envelope

Add regression coverage for both CLI consumers of the /api/providers connections envelope.

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>

---------

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
muhamadgalihsaputra pushed a commit to niyatna/NiyatnaRoute that referenced this pull request Sep 27, 2026
…pool and the ESLint gate (cheaper-inference#10726)

* fix(tests): drain the auto/glm base-red left by the Cloudflare Playground backend

provider-family-combos asserted a fixed provider list for auto/glm and started
failing on release/v3.8.50 once the Cloudflare AI Playground no-auth backend
landed: its registry advertises zai-org/glm-5.2 and zai-org/glm-4.7-flash, so the
virtual combo legitimately spans it.

The test already documents the rule it is failing on — a no-auth backend that
genuinely serves a family model IS a member of the family pool — and carries that
justification for auggie, devin-cli-agentic and zcode. Add cloudflare-playground
to the expectation with the same kind of source-cited note.

* fix(tests): green the ESLint gate left red by two untracked any casts

lint:json --max-warnings 0 failed on release/v3.8.50 because the suppression
counts drifted behind the tree: cli-oauth-commands carried 20 no-explicit-any
violations against a registered 18 (cheaper-inference#10491 added two Commander-mock casts) and
executor-gitlab carried 5 against a registered 4 (cheaper-inference#10499 added one).

The GitLab test casts are fixable, so they are fixed rather than suppressed: all
five now read the translated payload through a declared GitLabResponseBody
instead of any, and the file leaves the suppression list entirely.

The CLI OAuth casts target bin/cli/commands/oauth.mjs, which ships no types, so
the Commander mock has nothing to cast to; that entry only gets its count
corrected to the 20 already in the tree.
muhamadgalihsaputra pushed a commit to niyatna/NiyatnaRoute that referenced this pull request Sep 27, 2026
…eaper-inference#11236) (cheaper-inference#11263)

Residuals of cheaper-inference#11236 after cheaper-inference#10371/cheaper-inference#10491 landed on the tip:

- Dist-fold residuals (bugs 2+3): managedBinaryName() (binaryManager),
  resolveSpawnArgs() (installers/cliproxy) and the per-OS memory probes in
  getProcessInfo() (processManager) still read the process.platform literal,
  which the Linux build of the published artifact constant-folds (precedent:
  b71a339 / cheaper-inference#10244). Converted to call-time os.platform() reads, matching
  the module's documented anti-fold pattern. Test-side process.platform uses
  are not bundled and stay.
- Fold guard: new tests/unit/windows-platform-fold-guard-11236.test.ts pins
  zero out-of-comment process.platform occurrences in the four artifact
  runtime files, with a comment-stripping tokenizer plus mutation self-checks.
- Bug 6 (pid null on Windows): portProbe.resolvePortPid() only probed
  lsof/ss/net-tools netstat. Added a netstat -ano probe with a dedicated
  LISTENING-row parser (parseWindowsNetstatPid) as the last fallback; Unix
  probes unchanged, and the Windows parser never matches Unix rows (LISTEN vs
  LISTENING). Also converted the darwin args branch in the same array to
  os.platform() (same fold class, same hunk).
- Bug 5 hardening: runOAuthStatus coerces an out-of-contract 200 payload to
  an empty list with a sanitized stderr warning instead of crashing on
  .filter over a non-array.

TDD: guard test, parser tests and the oauth hardening test all failed RED
before the fix and pass GREEN after; sibling suites (binaryManager,
processManager, portProbePid, cli-oauth-commands, installers,
ServiceSupervisor, version-manager) green. The 6877 spawn-args test's win32
mock moved from defineProperty(process.platform) to
mock.method(os, "platform") to match the new runtime read — assertion
unchanged.

Co-authored-by: Xiangzhe <bakryun0718@proton.me>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants