Skip to content

fix(sdd): parse model string on first separator to fix OpenRouter /free bug#242

Closed
ACDPDEV wants to merge 1 commit into
Gentleman-Programming:mainfrom
ACDPDEV:fix/openrouter-free-suffix
Closed

fix(sdd): parse model string on first separator to fix OpenRouter /free bug#242
ACDPDEV wants to merge 1 commit into
Gentleman-Programming:mainfrom
ACDPDEV:fix/openrouter-free-suffix

Conversation

@ACDPDEV
Copy link
Copy Markdown

@ACDPDEV ACDPDEV commented Apr 6, 2026

Summary

  • Fix a parsing bug where OpenRouter free models were generated with an incorrect /free suffix instead of :free in opencode.json
  • Root cause: two parsing functions (extractModelFromAgent and ReadCurrentModelAssignments) incorrectly preferred : over / when splitting model strings, causing openrouter/qwen/qwen3.6-plus:free to be parsed as ProviderID=openrouter/qwen/qwen3.6-plus, ModelID=free
  • Fix: change both parsers to find the FIRST occurrence of either / or : (whichever comes first), matching the correct implementation already present in parseModelSpec (sync.go)
  • Verified: 118 existing tests pass, 19 provider format cases verified manually, end-to-end tested with OpenCode + OpenRouter free models

Why the first-separator rule works

The provider/model-id format in opencode.json is inherently ambiguous when the model ID contains slashes (OpenRouter IDs like qwen/qwen3.6-plus:free). All provider IDs are simple (never contain / or :), so finding the first separator correctly splits:

Input ProviderID ModelID
openrouter/qwen/qwen3.6-plus:free openrouter qwen/qwen3.6-plus:free
anthropic/claude-opus-4-6" anthropic claude-opus-4.6
opencode/qwen3.6-plus-free opencode qwen3.6-plus-free

Files Changed

  • internal/components/sdd/profiles.goextractModelFromAgent: first-separator parsing
  • internal/components/sdd/read_assignments.goReadCurrentModelAssignments: same fix + removed unused strings import

Testing

  • ✅ All 118 existing tests pass
  • ✅ 19 provider format cases verified (OpenRouter free/paid, OpenCode, Anthropic, OpenAI, Google, custom providers in parsing)
  • ✅ End-to-end tested with OpenCode + OpenRouter free API key

Closes #244

…ee bug

Both extractModelFromAgent and ReadCurrentModelAssignments incorrectly
preferred colon over slash when splitting model strings. For OpenRouter
free models like openrouter/qwen/qwen3.6-plus:free, this produced
openrouter/qwen/qwen3.6-plus/free instead of the correct :free suffix.

Fix: find the FIRST occurrence of either / or : (whichever comes first),
matching the correct implementation already present in parseModelSpec.
@nahuelalejandrogomez
Copy link
Copy Markdown

fsda

Copy link
Copy Markdown
Contributor

@Alan-TheGentleman Alan-TheGentleman left a comment

Choose a reason for hiding this comment

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

Review: APPROVE

Clean, correct, well-scoped fix. The first-separator approach matches the existing parseModelSpec in sync.go and correctly handles OpenRouter model IDs that contain both / and :.

Suggestions (non-blocking)

  1. Extract a shared helper — after this PR there are three identical copies of the "split on first / or :" logic (sync.go, profiles.go, read_assignments.go). A single splitProviderModel(s string) (string, string, bool) function would prevent this class of bug from recurring. Consider a follow-up.

  2. Add a regression test for the OpenRouter format. The existing tests in read_assignments_test.go only cover provider:model and provider/model — none cover the combined case openrouter/qwen/qwen3.6-plus:free that motivated this fix. Same for extractModelFromAgent, which has no dedicated test coverage at all.

Both are follow-ups, not blockers. The fix itself is correct.

@Alan-TheGentleman Alan-TheGentleman added the type:bug Bug fix label Apr 12, 2026
@ACDPDEV
Copy link
Copy Markdown
Author

ACDPDEV commented Apr 15, 2026

Actual issue: #260

@Basparin
Copy link
Copy Markdown
Contributor

Hola @ACDPDEV — me crucé con tu PR después de entrar al issue #260. El fix es elegante: buscar el primer separador (/ o :) en vez de preferir : primero. +8 LOC netos, Occam. Maneja exacto el caso openrouter/qwen/qwen3.6-plus:free.

Lo que veo en CI:

  • Unit Tests ✓
  • Check Issue Reference ✓
  • Check Issue Has status:approved ✓
  • Check PR Has type:* Label ✓
  • E2E Tests ✗ — 414/415 pasan, 2/3 platforms pasan, solo fedora falló 1 test

Ese fallo es de hace 2.5 semanas. main avanzó mucho desde entonces (v1.19→v1.23, múltiples refactors que tocan el área). Probablemente un rebase a main + re-trigger del CI desatasca todo. Si querés, te rebaseo yo desde el fork y mando un patch por comment, o te paso los pasos exactos. Solo decime.

También dejé un comment en #260 dirigido al reporter que quedó desalineado (no vi tu PR cuando lo escribí — mea culpa por búsqueda floja). Lo voy a editar para redirigir a acá.

Si preferís que no me meta, todo tranqui, me aparto. Tu PR, tu merge. Solo quería ofrecer desatascar el E2E si está frenado por drift.

@ACDPDEV
Copy link
Copy Markdown
Author

ACDPDEV commented Apr 24, 2026

Te dejo mano libre, me sería de mucha ayuda, ya no pude seguir con esto porque acabo de entrar a la universidad y ando muy atareado, más bien @Basparin te agradecería la ayuda.
Faltaría implementar las sugerencias de Alan, más que todo abstraer lo que se repite en una función.

@ACDPDEV
Copy link
Copy Markdown
Author

ACDPDEV commented Apr 24, 2026

Sí logras solucionar lo del E2E sería de mucha ayuda

@ACDPDEV
Copy link
Copy Markdown
Author

ACDPDEV commented Apr 29, 2026

This proposal is currently working on #374

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

Labels

type:bug Bug fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug(sdd): OpenRouter free models generated with /free suffix instead of :free

4 participants