Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/refine-api-key-login-copy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@moonshot-ai/kimi-code-oauth": patch
"@moonshot-ai/kimi-code": patch
---

Clarify Kimi Platform API key login labels and prompt details.
2 changes: 1 addition & 1 deletion apps/kimi-code/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ cd your-project
kimi
```

On first launch, run `/login` inside Kimi Code CLI and choose either Kimi Code OAuth or a Moonshot AI Open Platform API key. After login, try a first task:
On first launch, run `/login` inside Kimi Code CLI and choose either Kimi Code OAuth or a Kimi Platform API key. After login, try a first task:

```
Take a look at this project and explain the main directories.
Expand Down
8 changes: 7 additions & 1 deletion apps/kimi-code/src/tui/commands/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,13 @@ async function handleOpenPlatformLogin(
host: SlashCommandHost,
platform: OpenPlatformDefinition,
): Promise<void> {
const apiKey = await promptApiKey(host, platform.name);
const consoleHost = platform.consoleUrl?.replace(/^https?:\/\//, '') ?? '';
const platformName = consoleHost.length > 0 ? `Kimi Platform (${consoleHost})` : 'Kimi Platform';
const subtitleLines = [
`${'base_url'.padEnd(12)}${platform.baseUrl}`,
`${'saved to'.padEnd(12)}~/.kimi-code/config.toml`,
];
const apiKey = await promptApiKey(host, platformName, subtitleLines);
if (apiKey === undefined) return;

const controller = new AbortController();
Expand Down
7 changes: 6 additions & 1 deletion apps/kimi-code/src/tui/commands/prompts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,15 @@ export function promptFeedbackInput(host: SlashCommandHost): Promise<string | un
});
}

export function promptApiKey(host: SlashCommandHost, platformName: string): Promise<string | undefined> {
export function promptApiKey(
host: SlashCommandHost,
platformName: string,
subtitleLines: readonly string[] = ['Your key will be saved to ~/.kimi-code/config.toml'],
): Promise<string | undefined> {
return new Promise((resolve) => {
const dialog = new ApiKeyInputDialogComponent(
platformName,
subtitleLines,
(result: ApiKeyInputResult) => {
host.restoreEditor();
resolve(result.kind === 'ok' ? result.value : undefined);
Expand Down
22 changes: 16 additions & 6 deletions apps/kimi-code/src/tui/components/dialogs/api-key-input-dialog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,20 +49,21 @@ export class ApiKeyInputDialogComponent extends Container implements Focusable {
private readonly onDone: (result: ApiKeyInputResult) => void;
private readonly colors: ColorPalette;
private readonly title: string;
private readonly subtitle: string;
private readonly subtitleLines: readonly string[];
private done = false;
private emptyHinted = false;

constructor(
platformName: string,
subtitleLines: readonly string[],
onDone: (result: ApiKeyInputResult) => void,
colors: ColorPalette,
) {
super();
this.onDone = onDone;
this.colors = colors;
this.title = `Enter API key for ${platformName}`;
this.subtitle = 'Your key will be saved to ~/.kimi-code/config.toml';
this.subtitleLines = subtitleLines;
this.input.onSubmit = (value) => {
this.submit(value);
};
Expand Down Expand Up @@ -98,17 +99,26 @@ export class ApiKeyInputDialogComponent extends Container implements Focusable {

const border = (s: string): string => chalk.hex(this.colors.primary)(s);
const titleStyled = chalk.bold.hex(this.colors.textStrong)(this.title);
const subtitleText = this.emptyHinted ? 'API key cannot be empty.' : this.subtitle;
const subtitleStyled = chalk.hex(this.colors.textDim)(subtitleText);
const subtitleSource = this.emptyHinted ? ['API key cannot be empty.'] : this.subtitleLines;
const subtitleLines = subtitleSource.map((line) =>
truncateToWidth(chalk.hex(this.colors.textDim)(line), innerWidth, '…'),
);
const footerStyled = chalk.hex(this.colors.textDim)(FOOTER);

const titleLine = truncateToWidth(titleStyled, innerWidth, '…');
const subtitleLine = truncateToWidth(subtitleStyled, innerWidth, '…');
const footerLine = truncateToWidth(footerStyled, innerWidth, '…');
const rawInputLine = this.input.render(innerWidth)[0] ?? '> ';
const inputLine = this.input.getValue() === '' ? rawInputLine : maskInputLine(rawInputLine);

const contentLines: string[] = [titleLine, '', subtitleLine, '', inputLine, '', footerLine];
const contentLines: string[] = [
titleLine,
'',
...subtitleLines,
'',
inputLine,
'',
footerLine,
];

const lines: string[] = [
'',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { ChoicePickerComponent, type ChoiceOption } from './choice-picker';
import type { ColorPalette } from '#/tui/theme/colors';

const PLATFORM_OPTIONS: readonly ChoiceOption[] = [
{ value: 'kimi-code', label: 'Kimi Code' },
{ value: 'kimi-code', label: 'Kimi Code (OAuth)' },
...OPEN_PLATFORMS.map((platform) => ({ value: platform.id, label: platform.name })),
];

Expand Down
2 changes: 1 addition & 1 deletion docs/en/configuration/providers.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ The `type` field of each entry in the `providers` table determines which impleme

| Type | Protocol | Typical platforms |
| --- | --- | --- |
| `kimi` | OpenAI-compatible (chat completions style) | Kimi Code, Moonshot AI Open Platform |
| `kimi` | OpenAI-compatible (chat completions style) | Kimi Code, Kimi Platform API key |
| `anthropic` | Anthropic Messages | Claude API |
| `openai` | OpenAI Chat Completions | OpenAI and compatible services |
| `openai_responses` | OpenAI Responses API | OpenAI's newer Responses endpoint |
Expand Down
4 changes: 2 additions & 2 deletions docs/en/guides/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,8 @@ On the first launch, Kimi Code CLI has no credentials yet, and you need to confi

`/login` opens a platform selector supporting:

- **Kimi Code** — OAuth device code flow; open the URL on any device, sign in, and enter the code to authorize
- **Moonshot AI Open Platform** — log in directly with an API key
- **Kimi Code (OAuth)** — device code flow; open the URL on any device, sign in, and enter the code to authorize
- **Kimi Platform API key** — enter an API key from `platform.kimi.com` or `platform.kimi.ai`

To sign out, enter `/logout` to clear the current credentials.

Expand Down
2 changes: 1 addition & 1 deletion docs/en/reference/slash-commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Some commands are only available in the idle state. Running them while the sessi

| Command | Alias | Description | Always available |
| --- | --- | --- | --- |
| `/login` | — | Pick an account or platform and sign in: Kimi Code uses the OAuth device code flow, while the Moonshot AI Open Platform signs in with an API key. | No |
| `/login` | — | Pick an account or platform and sign in: Kimi Code uses the OAuth device code flow, while Kimi Platform signs in with an API key. | No |
| `/logout` | — | Clear the credentials of the currently selected account (Kimi Code OAuth credentials, or the corresponding open platform provider config). | No |
| `/connect [--refresh] [--url=<catalog-url>]` | — | Configure a provider and model from a model catalog. The default catalog is bundled with the CLI; pass `--refresh` to fetch the latest catalog from models.dev, or `--url` to read it from a custom URL. See [Providers and models — `/connect` and the model catalog](../configuration/providers.md#connect-and-the-model-catalog). | No |
| `/model` | — | Switch the LLM model used by the current session. | No |
Expand Down
2 changes: 1 addition & 1 deletion docs/zh/configuration/providers.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Kimi Code CLI 通过统一的供应商抽象对接多家 LLM 平台。每个供

| 类型 | 协议 | 典型平台 |
| --- | --- | --- |
| `kimi` | OpenAI 兼容(chat completions 风格) | Kimi Code、Moonshot AI 开放平台 |
| `kimi` | OpenAI 兼容(chat completions 风格) | Kimi Code、Kimi Platform API 密钥 |
| `anthropic` | Anthropic Messages | Claude API |
| `openai` | OpenAI Chat Completions | OpenAI 及其兼容服务 |
| `openai_responses` | OpenAI Responses API | OpenAI 较新的 Responses 接口 |
Expand Down
4 changes: 2 additions & 2 deletions docs/zh/guides/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,8 @@ kimi -C

`/login` 会弹出平台选择器,支持:

- **Kimi Code** — OAuth 验证码流程,在任意设备打开链接、登录并输入验证码即可授权
- **Moonshot AI Open Platform** — 直接输入 API key 登录
- **Kimi Code(OAuth)** — 验证码流程,在任意设备打开链接、登录并输入验证码即可授权
- **Kimi Platform API 密钥** — 输入来自 `platform.kimi.com` 或 `platform.kimi.ai` 的 API 密钥

需要退出登录时,输入 `/logout` 即可清除当前凭证。

Expand Down
2 changes: 1 addition & 1 deletion docs/zh/reference/slash-commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

| 命令 | 别名 | 说明 | 随时可用 |
| --- | --- | --- | --- |
| `/login` | — | 选择账号或平台并登录:Kimi Code 走 OAuth device code 流程,Moonshot AI 开放平台通过 API 密钥登录。 | 否 |
| `/login` | — | 选择账号或平台并登录:Kimi Code 走 OAuth 验证码流程,Kimi Platform 通过 API 密钥登录。 | 否 |
| `/logout` | — | 清除当前所选账号的凭据(Kimi Code OAuth 凭据,或对应开放平台的供应商配置)。 | 否 |
| `/connect [--refresh] [--url=<catalog-url>]` | — | 从模型目录中选择并配置供应商与模型。CLI 已内置默认目录;传入 `--refresh` 可从 models.dev 拉取最新目录,传入 `--url` 可指向自定义目录地址。详见 [平台与模型 — `/connect` 与模型目录](../configuration/providers.md#connect-与模型目录)。 | 否 |
| `/model` | — | 切换当前会话使用的 LLM 模型。 | 否 |
Expand Down
7 changes: 5 additions & 2 deletions packages/oauth/src/open-platform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,23 @@ export interface OpenPlatformDefinition {
readonly id: string;
readonly name: string;
readonly baseUrl: string;
readonly consoleUrl?: string;
readonly allowedPrefixes?: readonly string[] | undefined;
}

export const OPEN_PLATFORMS: readonly OpenPlatformDefinition[] = [
{
id: 'moonshot-cn',
name: 'Moonshot AI Open Platform (moonshot.cn)',
name: 'Kimi Platform (API key · platform.kimi.com)',
baseUrl: 'https://api.moonshot.cn/v1',
consoleUrl: 'https://platform.kimi.com',
allowedPrefixes: ['kimi-k'],
},
{
id: 'moonshot-ai',
name: 'Moonshot AI Open Platform (moonshot.ai)',
name: 'Kimi Platform (API key · platform.kimi.ai)',
baseUrl: 'https://api.moonshot.ai/v1',
consoleUrl: 'https://platform.kimi.ai',
allowedPrefixes: ['kimi-k'],
},
];
Expand Down
6 changes: 4 additions & 2 deletions packages/oauth/test/open-platform.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,15 @@ function makeModelsResponse(): Response {
describe('OPEN_PLATFORMS', () => {
it('contains moonshot.cn and moonshot.ai', () => {
expect(getOpenPlatformById('moonshot-cn')).toMatchObject({
name: 'Moonshot AI Open Platform (moonshot.cn)',
name: 'Kimi Platform (API key · platform.kimi.com)',
baseUrl: 'https://api.moonshot.cn/v1',
consoleUrl: 'https://platform.kimi.com',
allowedPrefixes: ['kimi-k'],
});
expect(getOpenPlatformById('moonshot-ai')).toMatchObject({
name: 'Moonshot AI Open Platform (moonshot.ai)',
name: 'Kimi Platform (API key · platform.kimi.ai)',
baseUrl: 'https://api.moonshot.ai/v1',
consoleUrl: 'https://platform.kimi.ai',
allowedPrefixes: ['kimi-k'],
});
expect(getOpenPlatformById('unknown')).toBeUndefined();
Expand Down
Loading