@@ -24,77 +24,42 @@ describe("OpencodeBackendDescriptor.wire.decode", () => {
2424 } ) ;
2525 } ) ;
2626
27- it ( "parses 3-segment ids as variants when the suffix is a known effort" , ( ) => {
28- expect ( decode ( "anthropic/claude-sonnet-4-5/medium" ) ) . toEqual ( {
29- selection : { baseModelId : "anthropic/claude-sonnet-4-5" , effort : "medium" } ,
30- provider : "anthropic" ,
31- } ) ;
32- expect ( decode ( "openai/gpt-5/minimal" ) ) . toEqual ( {
33- selection : { baseModelId : "openai/gpt-5" , effort : "minimal" } ,
34- provider : "openai" ,
35- } ) ;
36- } ) ;
37-
38- it ( "recognizes opencode's full effort vocabulary (none/minimal/low/medium/high/xhigh/max)" , ( ) => {
39- // Opencode advertises Anthropic models with `/max` and `/xhigh` and
40- // OpenRouter reasoning models with `/none`. Each must collapse onto
41- // its bare base.
42- for ( const effort of [ "none" , "minimal" , "low" , "medium" , "high" , "xhigh" , "max" ] ) {
43- expect ( decode ( `anthropic/claude-opus-4-7/${ effort } ` ) ) . toEqual ( {
44- selection : { baseModelId : "anthropic/claude-opus-4-7" , effort } ,
45- provider : "anthropic" ,
46- } ) ;
47- }
48- } ) ;
49-
50- it ( "returns no-effort representation for 3-segment ids whose suffix isn't a known effort" , ( ) => {
51- // OpenRouter-style 3-segment ids without an effort suffix — the
52- // trailing segment is part of the model name. The whole id is the
53- // baseModelId; provider is still attributed from the leading segment.
54- expect ( decode ( "openrouter/anthropic/claude-sonnet-4-5" ) ) . toEqual ( {
55- selection : { baseModelId : "openrouter/anthropic/claude-sonnet-4-5" , effort : null } ,
56- provider : "openrouterai" ,
57- } ) ;
27+ it ( "keeps an umbrella provider's id whole, attributing only the leading segment" , ( ) => {
28+ // `claude-3.5-haiku` and `gpt-5` are part of the model name, not an effort.
29+ // opencode reports effort as a separate `thought_level` config option, so no
30+ // trailing segment is ever peeled off.
5831 expect ( decode ( "openrouter/anthropic/claude-3.5-haiku" ) ) . toEqual ( {
5932 selection : { baseModelId : "openrouter/anthropic/claude-3.5-haiku" , effort : null } ,
6033 provider : "openrouterai" ,
6134 } ) ;
62- } ) ;
63-
64- it ( "parses 4-segment umbrella ids as variants when the last segment is a known effort" , ( ) => {
65- // OpenRouter wraps native ids under `openrouter/`, so its variants
66- // are 4-segment: `openrouter/<sub>/<model>/<effort>`. Without this
67- // case the picker would render seven duplicate rows per OpenRouter
68- // reasoning model.
69- expect ( decode ( "openrouter/anthropic/claude-sonnet-4.5/high" ) ) . toEqual ( {
70- selection : { baseModelId : "openrouter/anthropic/claude-sonnet-4.5" , effort : "high" } ,
71- provider : "openrouterai" ,
72- } ) ;
73- expect ( decode ( "openrouter/anthropic/claude-sonnet-4.5/none" ) ) . toEqual ( {
74- selection : { baseModelId : "openrouter/anthropic/claude-sonnet-4.5" , effort : "none" } ,
35+ expect ( decode ( "openrouter/openai/gpt-5" ) ) . toEqual ( {
36+ selection : { baseModelId : "openrouter/openai/gpt-5" , effort : null } ,
7537 provider : "openrouterai" ,
7638 } ) ;
77- expect ( decode ( "openrouter/openai/gpt-5/xhigh" ) ) . toEqual ( {
78- selection : { baseModelId : "openrouter/openai/gpt-5" , effort : "xhigh" } ,
39+ // OpenRouter route variants like `:exacto` live inside the model segment.
40+ expect ( decode ( "openrouter/openai/gpt-oss-120b:exacto" ) ) . toEqual ( {
41+ selection : { baseModelId : "openrouter/openai/gpt-oss-120b:exacto" , effort : null } ,
7942 provider : "openrouterai" ,
8043 } ) ;
81- // OpenRouter route variants like `:exacto` live inside the model
82- // segment — the effort suffix still attaches at the trailing slash.
83- expect ( decode ( "openrouter/openai/gpt-oss-120b:exacto/none" ) ) . toEqual ( {
84- selection : { baseModelId : "openrouter/openai/gpt-oss-120b:exacto" , effort : "none" } ,
85- provider : "openrouterai" ,
44+ } ) ;
45+
46+ it ( "keeps a trailing segment that reads like an effort, since effort never rides the id" , ( ) => {
47+ // A model literally named `.../high` would once have been mis-split into a
48+ // base model plus an effort. The vocabulary that made that possible is gone.
49+ expect ( decode ( "anthropic/claude-sonnet-4-5/high" ) ) . toEqual ( {
50+ selection : { baseModelId : "anthropic/claude-sonnet-4-5/high" , effort : null } ,
51+ provider : "anthropic" ,
8652 } ) ;
8753 } ) ;
8854
89- it ( "returns no-effort representation for unparseable shapes (1 segment or unknown trailing segment)" , ( ) => {
90- // 1-segment ids have no provider segment to attribute.
55+ it ( "attributes no provider to a single-segment id" , ( ) => {
9156 expect ( decode ( "just-a-name" ) ) . toEqual ( {
9257 selection : { baseModelId : "just-a-name" , effort : null } ,
9358 provider : null ,
9459 } ) ;
95- // 4+ segment ids whose trailing segment isn't a known effort fall
96- // through to a no-effort representation. The leading segment still
97- // attributes a provider when it maps.
60+ } ) ;
61+
62+ it ( " attributes a provider only when the leading segment maps to a Copilot one" , ( ) => {
9863 expect ( decode ( "anthropic/foo/bar/baz" ) ) . toEqual ( {
9964 selection : { baseModelId : "anthropic/foo/bar/baz" , effort : null } ,
10065 provider : "anthropic" ,
@@ -115,27 +80,22 @@ describe("OpencodeBackendDescriptor.wire.encode", () => {
11580 ) ;
11681 } ) ;
11782
118- it ( "appends the variant when effort is set " , ( ) => {
83+ it ( "drops effort, which opencode carries in its own config option rather than the id " , ( ) => {
11984 expect ( encode ( { baseModelId : "anthropic/claude-sonnet-4-5" , effort : "high" } ) ) . toBe (
120- "anthropic/claude-sonnet-4-5/high "
85+ "anthropic/claude-sonnet-4-5"
12186 ) ;
12287 } ) ;
12388
12489 it ( "round-trips via wire.decode" , ( ) => {
12590 const ids = [
12691 "anthropic/claude-sonnet-4-5" ,
127- "anthropic/claude-sonnet-4-5/low" ,
128- "openai/gpt-5/high" ,
129- "anthropic/claude-opus-4-7/max" ,
13092 "openrouter/anthropic/claude-sonnet-4.5" ,
131- "openrouter/anthropic/claude-sonnet-4.5/none" ,
132- "openrouter/anthropic/claude-sonnet-4.5/high" ,
93+ "openrouter/openai/gpt-oss-120b:exacto" ,
13394 // Catalog-less BYOK (openai-compatible) — provider id is the synthetic
13495 // copilot providerId, and the model id may itself contain slashes
13596 // (LM Studio repo-prefixed ids like `lmstudio-community/Qwen-…-GGUF`).
136- // The trailing segment isn't a known effort, so decode treats the
137- // whole string as `baseModelId` with `effort: null` — and encode
138- // reproduces it verbatim.
97+ // decode treats the whole string as `baseModelId`, and encode reproduces
98+ // it verbatim.
13999 "lmstudio-byok-id/lmstudio-community/Qwen2.5-7B-Instruct-GGUF" ,
140100 "ollama-byok-id/llama3.2" ,
141101 ] ;
0 commit comments