Kimi Code joins as an OAuth plan provider: RFC 8628 device flow, verified against the live endpoints
- New oauth/kimi-code-flow.ts mirrors the official kimi-cli: form-encoded device_authorization + token polling at auth.kimi.com with the required X-Msh-* device headers, pure poll interpreter, 15-minute tokens refreshed via refresh_token grant - Agent loop runs chat completions at https://api.kimi.com/coding/v1 with the Bearer access token; default model kimi-for-coding (kimi-for-coding-highspeed for Allegretto+ plans) - Live model listing via /coding/v1/models; credential refresh wired into the turn credential resolver - Migration 057 seeds the provider (disabled) into existing organizations - Wire protocol probed live: device code issued, authorization_pending poll observed, 401 envelope on the coding API confirmed
This commit is contained in:
1 parent
813276de71
commit
327de38e78
14 files changed
+281
-2
No files matched your search
@@ -28,6 +28,7 @@ import { refreshCodex } from "../oauth/openai-codex-flow";
|
||||
import { refreshClaudePro } from "../oauth/anthropic-claude-flow";
|
||||
import { refreshAntigravity } from "../oauth/google-antigravity-flow";
|
||||
import { refreshGitHubCopilotToken } from "../oauth/github-copilot-flow";
|
||||
import { refreshKimiCode } from "../oauth/kimi-code-flow";
|
||||
|
||||
interface StoredOAuth {
|
||||
access: string;
|
||||
@@ -63,6 +64,8 @@ function refreshOAuth(providerKey: string, creds: StoredOAuth): Promise<OAuthCre
|
||||
return refreshAntigravity(creds.refresh, creds.projectId);
|
||||
case "github-copilot":
|
||||
return refreshGitHubCopilotToken(creds.refresh, creds.enterpriseUrl ?? undefined);
|
||||
case "kimi-code":
|
||||
return refreshKimiCode(creds.refresh);
|
||||
default:
|
||||
throw new Error(`${providerKey} cannot refresh its credential.`);
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
runCopilotTurn,
|
||||
runCustomAnthropicTurn,
|
||||
runCustomOpenAiTurn,
|
||||
runKimiCodeTurn,
|
||||
runOpenAiResponsesTurn,
|
||||
runVertexTurn,
|
||||
} from "./turns";
|
||||
@@ -29,6 +30,7 @@ const TURNS: Record<string, ToolTurnFn> = {
|
||||
"github-copilot": runCopilotTurn,
|
||||
"google-antigravity": runAntigravityTurn,
|
||||
"claude-pro": runClaudeProTurn,
|
||||
"kimi-code": runKimiCodeTurn,
|
||||
"custom-openai": runCustomOpenAiTurn,
|
||||
"custom-anthropic": runCustomAnthropicTurn,
|
||||
"azure-openai": runAzureTurn,
|
||||
|
||||
@@ -14,6 +14,7 @@ import { bedrockToolConfig, parseBedrockOutput, toBedrockMessages } from "./bedr
|
||||
import { signAwsRequest } from "./aws-sigv4";
|
||||
import { getGcpAccessToken } from "./gcp-auth";
|
||||
import { COPILOT_HEADERS, copilotBaseUrl } from "../oauth/github-copilot-flow";
|
||||
import { KIMI_CODE_BASE_URL } from "../oauth/kimi-code-flow";
|
||||
|
||||
const ANTIGRAVITY_VERSION = "1.21.9";
|
||||
const ANTIGRAVITY_ENDPOINT = "https://cloudcode-pa.googleapis.com";
|
||||
@@ -108,6 +109,22 @@ export async function runClaudeProTurn(input: ProviderToolTurnInput): Promise<Ag
|
||||
return { ...parsed, rawResponseJson: JSON.stringify(response.data) };
|
||||
}
|
||||
|
||||
// ---- Kimi Code (OAuth plan, chat completions at the coding endpoint) ----
|
||||
|
||||
export async function runKimiCodeTurn(input: ProviderToolTurnInput): Promise<AgentTurnResult> {
|
||||
const access = requireAccessToken(input.credential, "Kimi Code");
|
||||
const body: JsonRecord = {
|
||||
model: input.model,
|
||||
messages: toChatMessages(input.instructions, input.messages),
|
||||
tools: chatToolDefs(input.tools),
|
||||
tool_choice: "auto",
|
||||
stream: false,
|
||||
};
|
||||
const response = await postJson(`${KIMI_CODE_BASE_URL}/chat/completions`, { authorization: `Bearer ${access}` }, body);
|
||||
const parsed = parseChatChoice(response.data);
|
||||
return { ...parsed, rawResponseJson: JSON.stringify(response.data) };
|
||||
}
|
||||
|
||||
// ---- GPT account / OpenAI Codex (OAuth, SSE) ----
|
||||
|
||||
export async function runCodexTurn(input: ProviderToolTurnInput): Promise<AgentTurnResult> {
|
||||
|
||||
Reference in new issue
Block a user