diff --git a/cmd/launch/integrations_test.go b/cmd/launch/integrations_test.go index ed844dc5e..0c909712b 100644 --- a/cmd/launch/integrations_test.go +++ b/cmd/launch/integrations_test.go @@ -301,7 +301,7 @@ func TestParseArgs(t *testing.T) { func TestIsCloudModel(t *testing.T) { // isCloudModel now only uses Show API, so nil client always returns false t.Run("nil client returns false", func(t *testing.T) { - models := []string{"glm-5.1:cloud", "kimi-k2.5:cloud", "local-model"} + models := []string{"glm-5.1:cloud", "kimi-k2.6:cloud", "local-model"} for _, model := range models { if isCloudModel(context.Background(), nil, model) { t.Errorf("isCloudModel(%q) with nil client should return false", model) @@ -321,7 +321,7 @@ func names(items []ModelItem) []string { func TestBuildModelList_NoExistingModels(t *testing.T) { items, _, _, _ := buildModelList(nil, nil, "") - want := []string{"kimi-k2.5:cloud", "qwen3.5:cloud", "glm-5.1:cloud", "minimax-m2.7:cloud", "gemma4", "qwen3.5"} + want := []string{"kimi-k2.6:cloud", "qwen3.5:cloud", "glm-5.1:cloud", "minimax-m2.7:cloud", "gemma4", "qwen3.5"} if diff := cmp.Diff(want, names(items)); diff != "" { t.Errorf("with no existing models, items should be recommended in order (-want +got):\n%s", diff) } @@ -350,7 +350,7 @@ func TestBuildModelList_OnlyLocalModels_CloudRecsStillFirst(t *testing.T) { // Cloud recs always come first among recommended, regardless of installed inventory. // Cloud disablement is handled upstream in loadSelectableModels via filterCloudItems. - want := []string{"kimi-k2.5:cloud", "qwen3.5:cloud", "glm-5.1:cloud", "minimax-m2.7:cloud", "gemma4", "qwen3.5", "llama3.2", "qwen2.5"} + want := []string{"kimi-k2.6:cloud", "qwen3.5:cloud", "glm-5.1:cloud", "minimax-m2.7:cloud", "gemma4", "qwen3.5", "llama3.2", "qwen2.5"} if diff := cmp.Diff(want, got); diff != "" { t.Errorf("cloud recs pinned first even when no cloud models installed (-want +got):\n%s", diff) } @@ -366,7 +366,7 @@ func TestBuildModelList_BothCloudAndLocal_RegularSort(t *testing.T) { got := names(items) // All recs pinned at top (cloud before local in mixed case), then non-recs - want := []string{"kimi-k2.5:cloud", "qwen3.5:cloud", "glm-5.1:cloud", "minimax-m2.7:cloud", "gemma4", "qwen3.5", "llama3.2"} + want := []string{"kimi-k2.6:cloud", "qwen3.5:cloud", "glm-5.1:cloud", "minimax-m2.7:cloud", "gemma4", "qwen3.5", "llama3.2"} if diff := cmp.Diff(want, got); diff != "" { t.Errorf("recs pinned at top, cloud recs first in mixed case (-want +got):\n%s", diff) } @@ -437,7 +437,7 @@ func TestBuildModelList_ExistingRecommendedMarked(t *testing.T) { if !strings.HasSuffix(item.Description, "(not downloaded)") { t.Errorf("non-installed recommended %q should have '(not downloaded)' suffix, got %q", item.Name, item.Description) } - case "minimax-m2.7:cloud", "kimi-k2.5:cloud", "qwen3.5:cloud": + case "minimax-m2.7:cloud", "kimi-k2.6:cloud", "qwen3.5:cloud": if strings.HasSuffix(item.Description, "(not downloaded)") { t.Errorf("cloud model %q should not have '(not downloaded)' suffix, got %q", item.Name, item.Description) } @@ -455,9 +455,9 @@ func TestBuildModelList_ExistingCloudModelsNotPushedToBottom(t *testing.T) { got := names(items) // gemma4 and glm-5.1:cloud are installed so they sort normally; - // kimi-k2.5:cloud, qwen3.5:cloud, and qwen3.5 are not installed so they go to the bottom + // qwen3.5:cloud and qwen3.5 are not installed so they go to the bottom // All recs: cloud first in mixed case, then local, in rec order within each - want := []string{"kimi-k2.5:cloud", "qwen3.5:cloud", "glm-5.1:cloud", "minimax-m2.7:cloud", "gemma4", "qwen3.5"} + want := []string{"kimi-k2.6:cloud", "qwen3.5:cloud", "glm-5.1:cloud", "minimax-m2.7:cloud", "gemma4", "qwen3.5"} if diff := cmp.Diff(want, got); diff != "" { t.Errorf("all recs, cloud first in mixed case (-want +got):\n%s", diff) } @@ -466,23 +466,23 @@ func TestBuildModelList_ExistingCloudModelsNotPushedToBottom(t *testing.T) { func TestBuildModelList_HasRecommendedCloudModel_OnlyNonInstalledAtBottom(t *testing.T) { existing := []modelInfo{ {Name: "llama3.2:latest", Remote: false}, - {Name: "kimi-k2.5:cloud", Remote: true}, + {Name: "kimi-k2.6:cloud", Remote: true}, } items, _, _, _ := buildModelList(existing, nil, "") got := names(items) - // kimi-k2.5:cloud is installed so it sorts normally; + // kimi-k2.6:cloud is installed so it sorts normally; // the rest of the recommendations are not installed so they go to the bottom // All recs pinned at top (cloud first in mixed case), then non-recs - want := []string{"kimi-k2.5:cloud", "qwen3.5:cloud", "glm-5.1:cloud", "minimax-m2.7:cloud", "gemma4", "qwen3.5", "llama3.2"} + want := []string{"kimi-k2.6:cloud", "qwen3.5:cloud", "glm-5.1:cloud", "minimax-m2.7:cloud", "gemma4", "qwen3.5", "llama3.2"} if diff := cmp.Diff(want, got); diff != "" { t.Errorf("recs pinned at top, cloud first in mixed case (-want +got):\n%s", diff) } for _, item := range items { isCloud := strings.HasSuffix(item.Name, ":cloud") - isInstalled := slices.Contains([]string{"kimi-k2.5:cloud", "llama3.2"}, item.Name) + isInstalled := slices.Contains([]string{"kimi-k2.6:cloud", "llama3.2"}, item.Name) if isInstalled || isCloud { if strings.HasSuffix(item.Description, "(not downloaded)") { t.Errorf("installed or cloud model %q should not have '(not downloaded)' suffix, got %q", item.Name, item.Description) @@ -549,8 +549,8 @@ func TestBuildModelList_ReturnsExistingAndCloudMaps(t *testing.T) { if !cloudModels["glm-5.1:cloud"] { t.Error("glm-5.1:cloud should be in cloudModels") } - if !cloudModels["kimi-k2.5:cloud"] { - t.Error("kimi-k2.5:cloud should be in cloudModels (recommended cloud)") + if !cloudModels["kimi-k2.6:cloud"] { + t.Error("kimi-k2.6:cloud should be in cloudModels (recommended cloud)") } if !cloudModels["qwen3.5:cloud"] { t.Error("qwen3.5:cloud should be in cloudModels (recommended cloud)") @@ -570,7 +570,7 @@ func TestBuildModelList_RecommendedFieldSet(t *testing.T) { for _, item := range items { switch item.Name { - case "gemma4", "qwen3.5", "glm-5.1:cloud", "kimi-k2.5:cloud", "qwen3.5:cloud": + case "gemma4", "qwen3.5", "glm-5.1:cloud", "kimi-k2.6:cloud", "qwen3.5:cloud": if !item.Recommended { t.Errorf("%q should have Recommended=true", item.Name) } @@ -628,7 +628,7 @@ func TestBuildModelList_RecsAboveNonRecs(t *testing.T) { lastRecIdx := -1 firstNonRecIdx := len(got) for i, name := range got { - isRec := name == "gemma4" || name == "qwen3.5" || name == "minimax-m2.7:cloud" || name == "glm-5.1:cloud" || name == "kimi-k2.5:cloud" || name == "qwen3.5:cloud" + isRec := name == "gemma4" || name == "qwen3.5" || name == "minimax-m2.7:cloud" || name == "glm-5.1:cloud" || name == "kimi-k2.6:cloud" || name == "qwen3.5:cloud" if isRec && i > lastRecIdx { lastRecIdx = i } diff --git a/cmd/launch/models.go b/cmd/launch/models.go index 2682aa102..e8d075ff9 100644 --- a/cmd/launch/models.go +++ b/cmd/launch/models.go @@ -21,7 +21,7 @@ import ( ) var recommendedModels = []ModelItem{ - {Name: "kimi-k2.5:cloud", Description: "Multimodal reasoning with subagents", Recommended: true}, + {Name: "kimi-k2.6:cloud", Description: "State-of-the-art coding, long-horizon execution, and multimodal agent swarm capability", Recommended: true}, {Name: "qwen3.5:cloud", Description: "Reasoning, coding, and agentic tool use with vision", Recommended: true}, {Name: "glm-5.1:cloud", Description: "Reasoning and code generation", Recommended: true}, {Name: "minimax-m2.7:cloud", Description: "Fast, efficient coding and real-world productivity", Recommended: true}, @@ -56,6 +56,7 @@ var cloudModelLimits = map[string]cloudModelLimit{ "gpt-oss:20b": {Context: 131_072, Output: 131_072}, "kimi-k2:1t": {Context: 262_144, Output: 262_144}, "kimi-k2.5": {Context: 262_144, Output: 262_144}, + "kimi-k2.6": {Context: 262_144, Output: 262_144}, "kimi-k2-thinking": {Context: 262_144, Output: 262_144}, "nemotron-3-nano:30b": {Context: 1_048_576, Output: 131_072}, "qwen3-coder:480b": {Context: 262_144, Output: 65_536},