fix(providers): make all models available in kilocode provider (#32352)

* kilocode: dynamic model discovery, kilo/auto default, cooldown exemption

- Replace 9-model hardcoded catalog with dynamic discovery from
  GET /api/gateway/models (Venice-like pattern with static fallback)
- Default model changed from anthropic/claude-opus-4.6 to kilo/auto
  (smart routing model)
- Add createKilocodeWrapper for X-KILOCODE-FEATURE header injection
  and reasoning.effort handling (skip for kilo/auto)
- Add kilocode to cooldown-exempt providers (proxy like OpenRouter)
- Keep sync buildKilocodeProvider for onboarding, add async
  buildKilocodeProviderWithDiscovery for implicit provider resolution
- Per-token gateway pricing converted to per-1M-token for cost fields

* kilocode: skip reasoning injection for x-ai models, harden discovery loop

* fix(kilocode): keep valid discovered duplicates (openclaw#32352, thanks @pandemicsyn)

* refactor(proxy): normalize reasoning payload guards (openclaw#32352, thanks @pandemicsyn)

* chore(changelog): note kilocode hardening (openclaw#32352, thanks @pandemicsyn and @vincentkoc)

* chore(changelog): fix kilocode note format (openclaw#32352, thanks @pandemicsyn and @vincentkoc)

* test(kilocode): support auto-model override cases (openclaw#32352, thanks @pandemicsyn)

* Update CHANGELOG.md

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
This commit is contained in:
Florian Hines
2026-03-07 10:14:06 -06:00
committed by GitHub
parent 786ec21b5a
commit 33e7394861
15 changed files with 832 additions and 168 deletions

View File

@@ -26,6 +26,7 @@ function makeStore(usageStats: AuthProfileStore["usageStats"]): AuthProfileStore
"anthropic:default": { type: "api_key", provider: "anthropic", key: "sk-test" },
"openai:default": { type: "api_key", provider: "openai", key: "sk-test-2" },
"openrouter:default": { type: "api_key", provider: "openrouter", key: "sk-or-test" },
"kilocode:default": { type: "api_key", provider: "kilocode", key: "sk-kc-test" },
},
usageStats,
};
@@ -120,6 +121,17 @@ describe("isProfileInCooldown", () => {
});
expect(isProfileInCooldown(store, "openrouter:default")).toBe(false);
});
it("returns false for Kilocode even when cooldown fields exist", () => {
const store = makeStore({
"kilocode:default": {
cooldownUntil: Date.now() + 60_000,
disabledUntil: Date.now() + 60_000,
disabledReason: "billing",
},
});
expect(isProfileInCooldown(store, "kilocode:default")).toBe(false);
});
});
describe("resolveProfilesUnavailableReason", () => {

View File

@@ -20,7 +20,8 @@ const FAILURE_REASON_ORDER = new Map<AuthProfileFailureReason, number>(
);
function isAuthCooldownBypassedForProvider(provider: string | undefined): boolean {
return normalizeProviderId(provider ?? "") === "openrouter";
const normalized = normalizeProviderId(provider ?? "");
return normalized === "openrouter" || normalized === "kilocode";
}
export function resolveProfileUnusableUntil(