From ab1698c3a32eb0a17af1d9234a3d27773d4e58cc Mon Sep 17 00:00:00 2001 From: Rolando Santamaria Maso Date: Wed, 29 Jul 2026 11:43:27 +0200 Subject: [PATCH] =?UTF-8?q?feat(agent):=20split=20k3=20profile=20context?= =?UTF-8?q?=20windows=20=E2=80=94=20k3=201M,=20k3-256k=20256K?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Longest-prefix matching gives k3-256k its own 256K entry while bare k3 keeps the 1M context window. Timeout stays 300s for both. --- docs/PROVIDERS.md | 4 +++- odek.go | 15 ++++++++++++--- odek_test.go | 20 +++++++++++++------- 3 files changed, 28 insertions(+), 11 deletions(-) diff --git a/docs/PROVIDERS.md b/docs/PROVIDERS.md index 95a5a0a..17fae2e 100644 --- a/docs/PROVIDERS.md +++ b/docs/PROVIDERS.md @@ -38,7 +38,9 @@ odek ships with built-in **model profiles** that automatically apply sensible de | `deepseek-chat` | DeepSeek (legacy) | (provider default) | 120s | 128K | General | | `deepseek-v4-flash` | DeepSeek v4 Flash | — (faster/cheaper) | 90s | 128K | Quick tasks, coding | | `deepseek-v4-pro` | DeepSeek v4 Pro | `enabled` | 180s | **1M** | Deep reasoning | -| `kimi-…`, `k3…` (e.g. `kimi-for-coding`, `k3-256k`) | Kimi | (provider default) | 300s | 256K | Agentic coding | +| `kimi-…` (e.g. `kimi-for-coding`) | Kimi | (provider default) | 300s | 256K | Agentic coding | +| `k3` | Kimi | (provider default) | 300s | **1M** | Agentic coding | +| `k3-256k` | Kimi | (provider default) | 300s | 256K | Agentic coding | | *(any other)* | Generic | (profile default) | 120s | (no limit) | Custom models | ### How profiles work diff --git a/odek.go b/odek.go index 1fcab9a..d98a53d 100644 --- a/odek.go +++ b/odek.go @@ -293,13 +293,22 @@ var KnownProfiles = []struct { }, }, { - // Kimi Code also ships models under the "k3" family name (k3, k3-256k), - // which the "kimi-" prefix does not match. + // Kimi Code also ships models under the "k3" family name, which the + // "kimi-" prefix does not match. Longest prefix wins: k3-256k is the + // 256K variant, bare k3 has a 1M context window. + Prefix: "k3-256k", + Profile: ModelProfile{ + Label: "Kimi", + Timeout: 300, + MaxContext: 262_144, // 256K token context window + }, + }, + { Prefix: "k3", Profile: ModelProfile{ Label: "Kimi", Timeout: 300, - MaxContext: 262_144, + MaxContext: 1_000_000, // 1M token context window }, }, { diff --git a/odek_test.go b/odek_test.go index 12e63ad..178477f 100644 --- a/odek_test.go +++ b/odek_test.go @@ -542,15 +542,21 @@ func TestLookupProfile_KimiMatch(t *testing.T) { t.Errorf("MaxContext = %d, want 262144", p.MaxContext) } - // The k3 family (k3, k3-256k) is the same Kimi Code line under a - // different prefix — it must get the same profile. - for _, model := range []string{"k3", "k3-256k"} { - p := LookupProfile(model) + // The k3 family is the same Kimi Code line under a different prefix — + // longest prefix wins: k3-256k is the 256K variant, bare k3 is 1M. + for _, tc := range []struct { + model string + maxContext int + }{ + {"k3", 1_000_000}, + {"k3-256k", 262_144}, + } { + p := LookupProfile(tc.model) if p == nil { - t.Fatalf("LookupProfile(%q) returned nil", model) + t.Fatalf("LookupProfile(%q) returned nil", tc.model) } - if p.Timeout != 300 || p.MaxContext != 262_144 { - t.Errorf("LookupProfile(%q) = %+v, want Timeout=300 MaxContext=262144", model, p) + if p.Timeout != 300 || p.MaxContext != tc.maxContext { + t.Errorf("LookupProfile(%q) = %+v, want Timeout=300 MaxContext=%d", tc.model, p, tc.maxContext) } } }