Skip to content

fix: handle openrouter compatibility aliases#57078

Closed
arkyu2077 wants to merge 1 commit into
openclaw:mainfrom
arkyu2077:fix/issue-57066
Closed

fix: handle openrouter compatibility aliases#57078
arkyu2077 wants to merge 1 commit into
openclaw:mainfrom
arkyu2077:fix/issue-57066

Conversation

@arkyu2077

Copy link
Copy Markdown
Contributor

Summary

Handle the two providerless OpenRouter compatibility shorthands before the legacy anthropic fallback kicks in.

Changes

  • resolve openrouter:auto directly to canonical openrouter/auto
  • resolve openrouter:free to the first configured concrete openrouter/...:free model
  • add regression tests for both compatibility aliases

Testing

  • Added targeted regression tests in src/agents/model-selection.test.ts
  • Local vitest execution on this host did not complete cleanly in time, so CI should be treated as the source of truth for the full suite

Fixes #57066

@openclaw-barnacle openclaw-barnacle Bot added agents Agent runtime and tooling size: S r: too-many-prs Auto-close: author has more than twenty active PRs. labels Mar 29, 2026
@openclaw-barnacle

Copy link
Copy Markdown

Closing this PR because the author has more than 10 active PRs in this repo. Please reduce the active PR queue and reopen or resubmit once it is back under the limit. You can close your own PRs to get back under the limit.

@greptile-apps

greptile-apps Bot commented Mar 29, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR introduces resolveOpenRouterCompatAlias, a helper that intercepts the two provider-less OpenRouter shorthands (openrouter:auto and openrouter:free) before the legacy Anthropic fallback fires. The openrouter:auto branch is straightforward and correct; the openrouter:free branch scans cfg.agents.defaults.models for the first openrouter/...:free entry, which is the right approach for ordered, user-controlled model preference.

Key observations:

  • openrouter:autonormalizeModelRef(\"openrouter\", \"auto\", …){ provider: \"openrouter\", model: \"openrouter/auto\" }. Matches expected behavior and the new test.
  • openrouter:free scanning uses Object.keys insertion order, which is deterministic in modern V8/Node but worth noting as the selection criterion.
  • Missing zero-match warning for openrouter:free: when no free model is configured, resolveOpenRouterCompatAlias returns null and the caller falls through to the Anthropic path, producing { provider: \"anthropic\", model: \"openrouter:free\" } — an invalid ref — with a misleading warning. A targeted log message should be added for this case.
  • No test covers the openrouter:free zero-match scenario.

Confidence Score: 4/5

Safe to merge for the happy paths, but the unguarded zero-match fallback for openrouter:free can produce a silently invalid Anthropic model ref that will fail at runtime.

Both new happy-path cases are correct and tested. The P1 finding is that openrouter:free with no configured free models falls through to the Anthropic fallback, returning an invalid model ref and a misleading warning. This is a present defect on the new feature path that should be fixed before merge.

src/agents/model-selection.ts — the zero-match return path at the end of resolveOpenRouterCompatAlias for the openrouter:free branch.

Important Files Changed

Filename Overview
src/agents/model-selection.ts Adds resolveOpenRouterCompatAlias to handle openrouter:auto (→ openrouter/auto) and openrouter:free (→ first configured free model). Happy paths are correct; the zero-match path for openrouter:free silently falls through to an invalid Anthropic fallback.
src/agents/model-selection.test.ts Adds two regression tests covering the new happy paths. Missing a test for the openrouter:free zero-match edge case.
Prompt To Fix All With AI
This is a comment left during a code review.
Path: src/agents/model-selection.ts
Line: 361-365

Comment:
**Silent invalid fallback when no free models are configured**

When `openrouter:free` is the primary model but no `openrouter/...:free` entries exist in `cfg.agents.defaults.models`, this function returns `null`. Execution then falls through to the legacy Anthropic path, which logs a misleading warning and returns `{ provider: "anthropic", model: "openrouter:free" }`. That model ref is invalid and will fail at the API level.

Since this function now owns the `openrouter:free` case, it should emit a targeted warning rather than silently delegating to the wrong code path. For example:

```ts
  // exhausted all configured models — warn explicitly before returning null
  getLog().warn(
    `"openrouter:free" was specified but no free OpenRouter models are configured under agents.defaults.models. ` +
      `Add at least one "openrouter/<vendor>/<model>:free" entry to your config.`,
  );
  return null;
```

Without this guard the caller still produces a bad `{ provider: "anthropic", model: "openrouter:free" }` ref, and the user sees "please use 'anthropic/openrouter:free' in your config" instead of a useful diagnostic.

How can I resolve this? If you propose a fix, please make it concise.

Reviews (1): Last reviewed commit: "fix: handle openrouter compatibility ali..." | Re-trigger Greptile

Comment on lines +361 to +365
return parsed;
}
}

return null;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Silent invalid fallback when no free models are configured

When openrouter:free is the primary model but no openrouter/...:free entries exist in cfg.agents.defaults.models, this function returns null. Execution then falls through to the legacy Anthropic path, which logs a misleading warning and returns { provider: "anthropic", model: "openrouter:free" }. That model ref is invalid and will fail at the API level.

Since this function now owns the openrouter:free case, it should emit a targeted warning rather than silently delegating to the wrong code path. For example:

  // exhausted all configured models — warn explicitly before returning null
  getLog().warn(
    `"openrouter:free" was specified but no free OpenRouter models are configured under agents.defaults.models. ` +
      `Add at least one "openrouter/<vendor>/<model>:free" entry to your config.`,
  );
  return null;

Without this guard the caller still produces a bad { provider: "anthropic", model: "openrouter:free" } ref, and the user sees "please use 'anthropic/openrouter:free' in your config" instead of a useful diagnostic.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/agents/model-selection.ts
Line: 361-365

Comment:
**Silent invalid fallback when no free models are configured**

When `openrouter:free` is the primary model but no `openrouter/...:free` entries exist in `cfg.agents.defaults.models`, this function returns `null`. Execution then falls through to the legacy Anthropic path, which logs a misleading warning and returns `{ provider: "anthropic", model: "openrouter:free" }`. That model ref is invalid and will fail at the API level.

Since this function now owns the `openrouter:free` case, it should emit a targeted warning rather than silently delegating to the wrong code path. For example:

```ts
  // exhausted all configured models — warn explicitly before returning null
  getLog().warn(
    `"openrouter:free" was specified but no free OpenRouter models are configured under agents.defaults.models. ` +
      `Add at least one "openrouter/<vendor>/<model>:free" entry to your config.`,
  );
  return null;
```

Without this guard the caller still produces a bad `{ provider: "anthropic", model: "openrouter:free" }` ref, and the user sees "please use 'anthropic/openrouter:free' in your config" instead of a useful diagnostic.

How can I resolve this? If you propose a fix, please make it concise.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c0fa592d9b

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

const configuredModels = params.cfg.agents?.defaults?.models ?? {};
for (const keyRaw of Object.keys(configuredModels)) {
const key = String(keyRaw ?? "").trim();
if (!key.startsWith("openrouter/")) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Normalize OpenRouter key match before filtering free aliases

resolveOpenRouterCompatAlias filters candidate keys with a case-sensitive key.startsWith("openrouter/"), so configs like agents.defaults.models["OpenRouter/meta-llama/...:free"] (which are valid per schema and otherwise normalized by parseModelRef) are skipped. In that scenario, selecting openrouter:free does not resolve to the configured free model and incorrectly falls through to the anthropic providerless fallback path.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling r: too-many-prs Auto-close: author has more than twenty active PRs. size: S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: OpenRouter compatibility aliases: openrouter:free resolves to anthropic/openrouter:free; openrouter:auto should also be handled explicitly

1 participant