mirror of
https://github.com/MoonshotAI/kimi-code.git
synced 2026-07-09 17:29:12 +00:00
fix: clarify Kimi Platform login copy (#274)
This commit is contained in:
parent
e2e17289fc
commit
a1dfbfeb16
14 changed files with 54 additions and 22 deletions
6
.changeset/refine-api-key-login-copy.md
Normal file
6
.changeset/refine-api-key-login-copy.md
Normal file
|
|
@ -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.
|
||||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -49,12 +49,13 @@ 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,
|
||||
) {
|
||||
|
|
@ -62,7 +63,7 @@ export class ApiKeyInputDialogComponent extends Container implements Focusable {
|
|||
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);
|
||||
};
|
||||
|
|
@ -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[] = [
|
||||
'',
|
||||
|
|
|
|||
|
|
@ -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 })),
|
||||
];
|
||||
|
||||
|
|
|
|||
|
|
@ -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 |
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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 |
|
||||
|
|
|
|||
|
|
@ -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 接口 |
|
||||
|
|
|
|||
|
|
@ -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` 即可清除当前凭证。
|
||||
|
||||
|
|
|
|||
|
|
@ -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 模型。 | 否 |
|
||||
|
|
|
|||
|
|
@ -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'],
|
||||
},
|
||||
];
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue