@ottocode/sdk 0.1.314 → 0.1.315
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/config/src/index.ts +2 -1
- package/src/config/src/manager.ts +1 -0
- package/src/core/src/providers/resolver.ts +1 -2
- package/src/core/src/tools/builtin/fs/edit.txt +1 -1
- package/src/core/src/tools/builtin/fs/index.ts +2 -0
- package/src/core/src/tools/builtin/fs/multiedit.txt +1 -1
- package/src/core/src/tools/builtin/glob.txt +4 -0
- package/src/core/src/tools/builtin/patch/indentation.ts +8 -1
- package/src/core/src/tools/builtin/patch/normalize.ts +4 -0
- package/src/core/src/tools/builtin/patch/repair.ts +42 -0
- package/src/core/src/tools/builtin/patch.txt +2 -0
- package/src/core/src/tools/builtin/search.txt +4 -0
- package/src/core/src/tools/builtin/shell.ts +46 -10
- package/src/core/src/tools/builtin/shell.txt +5 -0
- package/src/core/src/tools/loader.ts +8 -4
- package/src/index.ts +2 -5
- package/src/prompts/src/agents/build.txt +2 -2
- package/src/prompts/src/providers/{moonshot.txt → kimi.txt} +1 -1
- package/src/prompts/src/providers.ts +5 -5
- package/src/providers/src/catalog-manual.ts +41 -9
- package/src/providers/src/catalog.ts +74 -34
- package/src/providers/src/env.ts +4 -7
- package/src/providers/src/index.ts +3 -9
- package/src/providers/src/{moonshot-client.ts → kimi-client.ts} +131 -15
- package/src/providers/src/model-merge.ts +7 -1
- package/src/providers/src/pricing.ts +1 -1
- package/src/providers/src/registry.ts +8 -19
- package/src/providers/src/utils.ts +7 -8
- package/src/types/src/config.ts +1 -0
- package/src/types/src/provider.ts +4 -4
package/package.json
CHANGED
package/src/config/src/index.ts
CHANGED
|
@@ -25,7 +25,7 @@ const DEFAULT_PROVIDER_SETTINGS: OttoConfig['providers'] = {
|
|
|
25
25
|
xai: { enabled: false },
|
|
26
26
|
zai: { enabled: false },
|
|
27
27
|
'zai-coding': { enabled: false },
|
|
28
|
-
|
|
28
|
+
kimi: { enabled: false },
|
|
29
29
|
minimax: { enabled: false },
|
|
30
30
|
};
|
|
31
31
|
|
|
@@ -42,6 +42,7 @@ const DEFAULTS: {
|
|
|
42
42
|
reasoningText: true,
|
|
43
43
|
reasoningLevel: 'high',
|
|
44
44
|
theme: 'dark',
|
|
45
|
+
tuiTheme: 'tokyo-night',
|
|
45
46
|
vimMode: false,
|
|
46
47
|
compactThread: true,
|
|
47
48
|
fontFamily: 'IBM Plex Mono',
|
|
@@ -33,7 +33,6 @@ export type ProviderName =
|
|
|
33
33
|
| 'xai'
|
|
34
34
|
| 'zai'
|
|
35
35
|
| 'zai-coding'
|
|
36
|
-
| 'moonshot'
|
|
37
36
|
| 'kimi'
|
|
38
37
|
| 'minimax';
|
|
39
38
|
|
|
@@ -222,7 +221,7 @@ export async function resolveModel(
|
|
|
222
221
|
});
|
|
223
222
|
}
|
|
224
223
|
|
|
225
|
-
if (provider === '
|
|
224
|
+
if (provider === 'kimi') {
|
|
226
225
|
return createKimiModel(model, {
|
|
227
226
|
apiKey: config.apiKey,
|
|
228
227
|
baseURL: config.baseURL,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Replace an exact text block in an existing file.
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Prefer `apply_patch` for most code/text edits when it is available, because it produces the clearest diff preview. Use `edit` when you have one precise old/new text replacement, when a patch would be awkward, or after patch attempts fail.
|
|
4
4
|
|
|
5
5
|
Rules:
|
|
6
6
|
- You must read the file first in the current session before editing it.
|
|
@@ -9,6 +9,8 @@ import { buildTreeTool } from './tree.ts';
|
|
|
9
9
|
import { buildPwdTool } from './pwd.ts';
|
|
10
10
|
import { buildCdTool } from './cd.ts';
|
|
11
11
|
|
|
12
|
+
export { rememberFileRead } from './read-tracker.ts';
|
|
13
|
+
|
|
12
14
|
export function buildFsTools(
|
|
13
15
|
projectRoot: string,
|
|
14
16
|
): Array<{ name: string; tool: Tool }> {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Apply multiple exact text replacements to a single existing file atomically.
|
|
2
2
|
|
|
3
|
-
Use
|
|
3
|
+
Prefer `apply_patch` for most code/text edits when it is available, especially when a diff is easy to express. Use `multiedit` when you have several precise old/new replacements in one file, when a patch would be awkward, or after patch attempts fail.
|
|
4
4
|
|
|
5
5
|
Rules:
|
|
6
6
|
- Read the file first before editing.
|
|
@@ -6,8 +6,12 @@
|
|
|
6
6
|
|
|
7
7
|
**Use `glob` first to discover files** before reading them, unless you already know exact paths.
|
|
8
8
|
|
|
9
|
+
Think of `glob` as the repository's fast local `find` replacement for filenames and paths. Use it before shelling out to `find`, `fd`, or `ls **`.
|
|
10
|
+
|
|
9
11
|
## Usage tips
|
|
10
12
|
|
|
11
13
|
- Use `glob` for filename patterns; use `search` for file contents.
|
|
12
14
|
- Combine with `path` to restrict the search to a subdirectory.
|
|
13
15
|
- Prefer reading a known file directly over globbing to "find" it (check the `<project>` listing in the system prompt first).
|
|
16
|
+
- Instead of `find packages -name "*.ts"`, call `glob` with `pattern: "packages/**/*.ts"`.
|
|
17
|
+
- Instead of `find apps -name package.json`, call `glob` with `pattern: "apps/**/package.json"`.
|
|
@@ -23,6 +23,7 @@ export function adjustReplacementIndentation(
|
|
|
23
23
|
let fileIndentChar: 'tab' | 'space' = 'space';
|
|
24
24
|
const deltas: number[] = [];
|
|
25
25
|
let hasAddStyleMismatch = false;
|
|
26
|
+
let hasContextContentMismatch = false;
|
|
26
27
|
let fileIndentDetected = false;
|
|
27
28
|
|
|
28
29
|
for (const fl of matchedFileLines) {
|
|
@@ -81,6 +82,7 @@ export function adjustReplacementIndentation(
|
|
|
81
82
|
if (line.kind === 'context') {
|
|
82
83
|
const fileLine = matchedFileLines[expectedIdx];
|
|
83
84
|
if (fileLine !== undefined) {
|
|
85
|
+
if (line.content !== fileLine) hasContextContentMismatch = true;
|
|
84
86
|
lastDelta = computeIndentDelta(line.content, fileLine, tabSize);
|
|
85
87
|
lastFileIndentExpanded = expandWhitespace(
|
|
86
88
|
getLeadingWhitespace(fileLine),
|
|
@@ -152,7 +154,12 @@ export function adjustReplacementIndentation(
|
|
|
152
154
|
}
|
|
153
155
|
}
|
|
154
156
|
|
|
155
|
-
if (
|
|
157
|
+
if (
|
|
158
|
+
!hasDelta &&
|
|
159
|
+
!hasStyleMismatch &&
|
|
160
|
+
!hasAddStyleMismatch &&
|
|
161
|
+
!hasContextContentMismatch
|
|
162
|
+
) {
|
|
156
163
|
return hunk.lines.filter((l) => l.kind !== 'remove').map((l) => l.content);
|
|
157
164
|
}
|
|
158
165
|
|
|
@@ -3,6 +3,7 @@ enum NormalizationLevel {
|
|
|
3
3
|
TABS_ONLY = 'tabs',
|
|
4
4
|
WHITESPACE = 'whitespace',
|
|
5
5
|
AGGRESSIVE = 'aggressive',
|
|
6
|
+
COLLAPSED = 'collapsed',
|
|
6
7
|
}
|
|
7
8
|
|
|
8
9
|
const DEFAULT_TAB_SIZE = 2;
|
|
@@ -22,6 +23,8 @@ export function normalizeWhitespace(
|
|
|
22
23
|
return line.replace(/\t/g, tabReplacement).replace(/\s+$/, '');
|
|
23
24
|
case NormalizationLevel.AGGRESSIVE:
|
|
24
25
|
return line.replace(/\t/g, tabReplacement).trim();
|
|
26
|
+
case NormalizationLevel.COLLAPSED:
|
|
27
|
+
return line.replace(/\t/g, tabReplacement).trim().replace(/\s+/g, ' ');
|
|
25
28
|
default:
|
|
26
29
|
return line;
|
|
27
30
|
}
|
|
@@ -32,6 +35,7 @@ export const NORMALIZATION_LEVELS: NormalizationLevel[] = [
|
|
|
32
35
|
NormalizationLevel.TABS_ONLY,
|
|
33
36
|
NormalizationLevel.WHITESPACE,
|
|
34
37
|
NormalizationLevel.AGGRESSIVE,
|
|
38
|
+
NormalizationLevel.COLLAPSED,
|
|
35
39
|
];
|
|
36
40
|
|
|
37
41
|
export function getLeadingWhitespace(line: string): string {
|
|
@@ -13,10 +13,30 @@ import {
|
|
|
13
13
|
|
|
14
14
|
export function repairPatchContent(patch: string): string {
|
|
15
15
|
patch = extractPatchFromWrappedJson(patch);
|
|
16
|
+
patch = extractEnvelopedPatchFromText(patch);
|
|
17
|
+
patch = stripTrailingMarkdownFenceBeforeMissingEndMarker(patch);
|
|
16
18
|
patch = appendMissingEndMarker(patch);
|
|
19
|
+
patch = trimAfterEndMarker(patch);
|
|
17
20
|
return patch;
|
|
18
21
|
}
|
|
19
22
|
|
|
23
|
+
function looksLikeUnifiedPatch(patch: string): boolean {
|
|
24
|
+
const trimmed = patch.trimStart();
|
|
25
|
+
return (
|
|
26
|
+
trimmed.startsWith('diff --git ') ||
|
|
27
|
+
trimmed.startsWith('--- ') ||
|
|
28
|
+
trimmed.startsWith('Index: ')
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function extractEnvelopedPatchFromText(patch: string): string {
|
|
33
|
+
const beginIndex = patch.indexOf(PATCH_BEGIN_MARKER);
|
|
34
|
+
if (beginIndex === -1) return patch;
|
|
35
|
+
if (beginIndex === patch.search(/\S/)) return patch;
|
|
36
|
+
if (looksLikeUnifiedPatch(patch)) return patch;
|
|
37
|
+
return patch.slice(beginIndex);
|
|
38
|
+
}
|
|
39
|
+
|
|
20
40
|
function extractPatchFromWrappedJson(patch: string): string {
|
|
21
41
|
if (patch.includes(PATCH_BEGIN_MARKER)) return patch;
|
|
22
42
|
|
|
@@ -61,3 +81,25 @@ function appendMissingEndMarker(patch: string): string {
|
|
|
61
81
|
|
|
62
82
|
return patch;
|
|
63
83
|
}
|
|
84
|
+
|
|
85
|
+
function stripTrailingMarkdownFenceBeforeMissingEndMarker(
|
|
86
|
+
patch: string,
|
|
87
|
+
): string {
|
|
88
|
+
const trimmed = patch.trimEnd();
|
|
89
|
+
if (!trimmed.trimStart().startsWith(PATCH_BEGIN_MARKER)) return patch;
|
|
90
|
+
if (trimmed.includes(PATCH_END_MARKER)) return patch;
|
|
91
|
+
const lines = trimmed.split('\n');
|
|
92
|
+
const last = lines.at(-1)?.trim();
|
|
93
|
+
if (last !== '```') return patch;
|
|
94
|
+
return lines.slice(0, -1).join('\n');
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function trimAfterEndMarker(patch: string): string {
|
|
98
|
+
if (!patch.trimStart().startsWith(PATCH_BEGIN_MARKER)) return patch;
|
|
99
|
+
const endIndex = patch.indexOf(PATCH_END_MARKER);
|
|
100
|
+
if (endIndex === -1) return patch;
|
|
101
|
+
const endOfMarker = endIndex + PATCH_END_MARKER.length;
|
|
102
|
+
const suffix = patch.slice(endOfMarker);
|
|
103
|
+
if (suffix.trim().length === 0) return patch;
|
|
104
|
+
return patch.slice(0, endOfMarker);
|
|
105
|
+
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
Apply a patch to modify one or more files.
|
|
2
2
|
|
|
3
|
+
Prefer this as the first-choice editing tool for code and text changes when it is available. Use exact-replacement tools (`edit`/`multiedit`) when a patch would be awkward, when you only need a precise old/new string replacement, or after patch attempts fail.
|
|
4
|
+
|
|
3
5
|
Use the **enveloped format** by default. Standard unified diffs (`---` / `+++`) are also accepted.
|
|
4
6
|
|
|
5
7
|
## Fastest / safest mode (recommended): Replace
|
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
|
|
6
6
|
Use this for text/code search across the codebase. It is the primary tool for repository content discovery.
|
|
7
7
|
|
|
8
|
+
Think of `search` as the repository's fast local `rg`/`grep` replacement: use it for exact string and regex searches before reaching for shell commands.
|
|
9
|
+
|
|
8
10
|
## Usage tips
|
|
9
11
|
|
|
10
12
|
- Narrow broad searches with `path` and `glob` values.
|
|
@@ -12,3 +14,5 @@ Use this for text/code search across the codebase. It is the primary tool for re
|
|
|
12
14
|
- Batch independent searches (e.g. multiple function names) in a single turn for parallel execution.
|
|
13
15
|
- Use `ignoreCase: true` for case-insensitive matching; pass `glob` patterns (e.g. `["*.ts", "*.tsx"]`) to limit file types.
|
|
14
16
|
- For filename/path discovery, use `glob` first when you already know the file pattern.
|
|
17
|
+
- Instead of `grep -r "workspace:" packages apps`, call `search` with `query: "workspace:"`, `path: "."`, and `glob: ["**/package.json"]`.
|
|
18
|
+
- Instead of `rg "function foo" src`, call `search` with `query: "function foo"` and `path: "src"`.
|
|
@@ -46,6 +46,7 @@ function killProcessTree(pid: number) {
|
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
const REDIRECTED_SEARCH_COMMANDS = new Set(['grep', 'egrep', 'fgrep', 'rg']);
|
|
49
|
+
const REDIRECTED_GLOB_COMMANDS = new Set(['find', 'fd']);
|
|
49
50
|
|
|
50
51
|
/**
|
|
51
52
|
* Detect commands that start with a standalone grep-style search binary.
|
|
@@ -53,23 +54,55 @@ const REDIRECTED_SEARCH_COMMANDS = new Set(['grep', 'egrep', 'fgrep', 'rg']);
|
|
|
53
54
|
* with grep/rg are redirected to the dedicated `search` tool.
|
|
54
55
|
*/
|
|
55
56
|
export function findRedirectedSearchCommand(cmd: string): string | null {
|
|
57
|
+
return findRepositoryDiscoveryCommand(cmd, 'search')?.command ?? null;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function commandTokens(segment: string): string[] {
|
|
61
|
+
const tokens = segment.trim().split(/\s+/).filter(Boolean);
|
|
62
|
+
let index = 0;
|
|
63
|
+
while (
|
|
64
|
+
index < tokens.length &&
|
|
65
|
+
/^[A-Za-z_][A-Za-z0-9_]*=/.test(tokens[index] ?? '')
|
|
66
|
+
) {
|
|
67
|
+
index++;
|
|
68
|
+
}
|
|
69
|
+
if (tokens[index] === 'command') index++;
|
|
70
|
+
return tokens.slice(index);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function findRepositoryDiscoveryCommand(
|
|
74
|
+
cmd: string,
|
|
75
|
+
kind?: 'search' | 'glob',
|
|
76
|
+
): { command: string; tool: 'search' | 'glob' } | null {
|
|
56
77
|
const segments = cmd.split(/&&|\|\||;|\n/);
|
|
57
78
|
for (const segment of segments) {
|
|
58
|
-
const tokens = segment
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
79
|
+
const tokens = commandTokens(segment);
|
|
80
|
+
const bin = tokens[0]?.split('/').pop() ?? '';
|
|
81
|
+
const second = tokens[1] ?? '';
|
|
82
|
+
if ((!kind || kind === 'search') && bin === 'git' && second === 'grep') {
|
|
83
|
+
return { command: 'git grep', tool: 'search' };
|
|
84
|
+
}
|
|
85
|
+
if ((!kind || kind === 'search') && REDIRECTED_SEARCH_COMMANDS.has(bin)) {
|
|
86
|
+
return { command: bin, tool: 'search' };
|
|
87
|
+
}
|
|
88
|
+
if ((!kind || kind === 'glob') && REDIRECTED_GLOB_COMMANDS.has(bin)) {
|
|
89
|
+
return { command: bin, tool: 'glob' };
|
|
90
|
+
}
|
|
91
|
+
if ((!kind || kind === 'glob') && bin === 'ls' && segment.includes('**')) {
|
|
92
|
+
return { command: 'ls **', tool: 'glob' };
|
|
65
93
|
}
|
|
66
|
-
if (tokens[index] === 'command') index++;
|
|
67
|
-
const bin = tokens[index]?.split('/').pop() ?? '';
|
|
68
|
-
if (REDIRECTED_SEARCH_COMMANDS.has(bin)) return bin;
|
|
69
94
|
}
|
|
70
95
|
return null;
|
|
71
96
|
}
|
|
72
97
|
|
|
98
|
+
function repositoryDiscoveryHint(cmd: string): string | undefined {
|
|
99
|
+
const discovery = findRepositoryDiscoveryCommand(cmd);
|
|
100
|
+
if (!discovery) return undefined;
|
|
101
|
+
return discovery.tool === 'search'
|
|
102
|
+
? `Tip: For repository content search, prefer the search tool instead of shelling out to ${discovery.command}. It is indexed, faster, and returns structured file:line matches.`
|
|
103
|
+
: `Tip: For repository file discovery, prefer the glob tool instead of shelling out to ${discovery.command}. It returns structured paths and skips common build/cache folders.`;
|
|
104
|
+
}
|
|
105
|
+
|
|
73
106
|
export type ShellOutputMode = 'auto' | 'full' | 'tail';
|
|
74
107
|
|
|
75
108
|
const DEFAULT_TAIL_LINES = 100;
|
|
@@ -136,6 +169,7 @@ type ShellResult = ToolResponse<{
|
|
|
136
169
|
stderrTruncated?: boolean;
|
|
137
170
|
stderrOriginalBytes?: number;
|
|
138
171
|
stderrShownBytes?: number;
|
|
172
|
+
discoveryHint?: string;
|
|
139
173
|
}>;
|
|
140
174
|
|
|
141
175
|
type ShellStreamChunk =
|
|
@@ -446,11 +480,13 @@ export function buildShellTool(projectRoot: string): {
|
|
|
446
480
|
return;
|
|
447
481
|
}
|
|
448
482
|
|
|
483
|
+
const discoveryHint = repositoryDiscoveryHint(finalCmd);
|
|
449
484
|
settle({
|
|
450
485
|
ok: true,
|
|
451
486
|
exitCode: exitCode ?? 0,
|
|
452
487
|
stdout,
|
|
453
488
|
stderr,
|
|
489
|
+
...(discoveryHint ? { discoveryHint } : {}),
|
|
454
490
|
...(outputMode === 'tail' || outputMode === 'auto'
|
|
455
491
|
? { outputMode, tailLines, maxOutputBytes }
|
|
456
492
|
: { outputMode, maxOutputBytes }),
|
|
@@ -8,6 +8,11 @@ For repository discovery, use `search` for content/code search and `glob` for fi
|
|
|
8
8
|
|
|
9
9
|
**Strongly prefer the `search` tool over `grep`/`rg`, and `glob` over `find`.** The `search` tool is indexed and faster, returns structured `file:line` matches, and supports regex, `glob` includes, `path` scoping, and `ignoreCase` — use it for all repository content search. Only fall back to `grep`/`rg` via shell for cases `search` cannot handle (e.g. gitignored files like node_modules or build output). Pipelines that filter program output (e.g. `ps aux | grep node`) are fine.
|
|
10
10
|
|
|
11
|
+
Mapping from common shell habits:
|
|
12
|
+
- `grep -r` / `rg` / `git grep` over repo files → use `search`.
|
|
13
|
+
- `find` / `fd` / recursive `ls` for filenames → use `glob`.
|
|
14
|
+
- Build, test, package manager, diagnostics, process inspection → use `shell`.
|
|
15
|
+
|
|
11
16
|
## Usage tips
|
|
12
17
|
|
|
13
18
|
- Chain commands with `&&` to fail-fast.
|
|
@@ -142,7 +142,14 @@ async function discoverStaticProjectTools(
|
|
|
142
142
|
|
|
143
143
|
const discoveryPromise = (async () => {
|
|
144
144
|
const tools = new Map<string, Tool>();
|
|
145
|
-
|
|
145
|
+
const fsTools = buildFsTools(projectRoot);
|
|
146
|
+
for (const { name, tool } of fsTools.filter(({ name }) => name === 'read'))
|
|
147
|
+
tools.set(name, tool);
|
|
148
|
+
// Put apply_patch before exact replacement tools so models see it as the
|
|
149
|
+
// default editing path after reading files.
|
|
150
|
+
const ap = buildApplyPatchTool(projectRoot);
|
|
151
|
+
tools.set(ap.name, ap.tool);
|
|
152
|
+
for (const { name, tool } of fsTools.filter(({ name }) => name !== 'read'))
|
|
146
153
|
tools.set(name, tool);
|
|
147
154
|
for (const { name, tool } of buildGitTools(projectRoot))
|
|
148
155
|
tools.set(name, tool);
|
|
@@ -155,9 +162,6 @@ async function discoverStaticProjectTools(
|
|
|
155
162
|
tools.set(search.name, search.tool);
|
|
156
163
|
const glob = buildGlobTool(projectRoot);
|
|
157
164
|
tools.set(glob.name, glob.tool);
|
|
158
|
-
// Patch/apply
|
|
159
|
-
const ap = buildApplyPatchTool(projectRoot);
|
|
160
|
-
tools.set(ap.name, ap.tool);
|
|
161
165
|
// Todo tracking
|
|
162
166
|
tools.set('update_todos', updateTodosTool);
|
|
163
167
|
// Web search
|
package/src/index.ts
CHANGED
|
@@ -81,6 +81,7 @@ export type {
|
|
|
81
81
|
} from './providers/src/index.ts';
|
|
82
82
|
export {
|
|
83
83
|
isBuiltInProviderId,
|
|
84
|
+
resolveBuiltInProviderCatalogId,
|
|
84
85
|
getProviderSettings,
|
|
85
86
|
getProviderDefinition,
|
|
86
87
|
hasConfiguredProvider,
|
|
@@ -162,13 +163,9 @@ export { createOpencodeModel } from './providers/src/index.ts';
|
|
|
162
163
|
export type { OpencodeProviderConfig } from './providers/src/index.ts';
|
|
163
164
|
export {
|
|
164
165
|
createKimiModel,
|
|
165
|
-
createMoonshotModel,
|
|
166
166
|
readKimiApiKeyFromEnv,
|
|
167
167
|
} from './providers/src/index.ts';
|
|
168
|
-
export type {
|
|
169
|
-
KimiProviderConfig,
|
|
170
|
-
MoonshotProviderConfig,
|
|
171
|
-
} from './providers/src/index.ts';
|
|
168
|
+
export type { KimiProviderConfig } from './providers/src/index.ts';
|
|
172
169
|
export { createMinimaxModel } from './providers/src/index.ts';
|
|
173
170
|
export type { MinimaxProviderConfig } from './providers/src/index.ts';
|
|
174
171
|
export {
|
|
@@ -8,8 +8,8 @@ You help with coding and build tasks.
|
|
|
8
8
|
|
|
9
9
|
Pick the right tool for the job (each tool's description has its full contract):
|
|
10
10
|
|
|
11
|
-
-
|
|
12
|
-
- Use
|
|
11
|
+
- Prefer `apply_patch` for code and text changes when it is available. It gives the clearest diff preview and handles targeted, structural, and multi-file edits.
|
|
12
|
+
- Use exact-replacement tools (`edit`/`multiedit`) when a patch would be awkward, when you have a precise replacement block, or after patch attempts fail.
|
|
13
13
|
- Use `write` only for NEW files or >70% full-file rewrites. Never use it for targeted edits.
|
|
14
14
|
|
|
15
15
|
**Always read a file immediately before editing it.** Memory and earlier context are not reliable — the file may have changed.
|
|
@@ -14,7 +14,7 @@ import PROVIDER_ANTHROPIC from './providers/anthropic.txt' with {
|
|
|
14
14
|
// eslint-disable-next-line @typescript-eslint/consistent-type-imports
|
|
15
15
|
import PROVIDER_GOOGLE from './providers/google.txt' with { type: 'text' };
|
|
16
16
|
// eslint-disable-next-line @typescript-eslint/consistent-type-imports
|
|
17
|
-
import
|
|
17
|
+
import PROVIDER_KIMI from './providers/kimi.txt' with { type: 'text' };
|
|
18
18
|
// eslint-disable-next-line @typescript-eslint/consistent-type-imports
|
|
19
19
|
import PROVIDER_DEFAULT from './providers/default.txt' with { type: 'text' };
|
|
20
20
|
// eslint-disable-next-line @typescript-eslint/consistent-type-imports
|
|
@@ -24,7 +24,7 @@ const FAMILY_PROMPTS: Record<string, string> = {
|
|
|
24
24
|
openai: PROVIDER_OPENAI,
|
|
25
25
|
anthropic: PROVIDER_ANTHROPIC,
|
|
26
26
|
google: PROVIDER_GOOGLE,
|
|
27
|
-
|
|
27
|
+
kimi: PROVIDER_KIMI,
|
|
28
28
|
glm: PROVIDER_GLM,
|
|
29
29
|
minimax: PROVIDER_DEFAULT,
|
|
30
30
|
};
|
|
@@ -142,9 +142,9 @@ export async function providerBasePrompt(
|
|
|
142
142
|
const result = PROVIDER_GOOGLE.trim();
|
|
143
143
|
return { prompt: result, resolvedType: 'google' };
|
|
144
144
|
}
|
|
145
|
-
if (id === '
|
|
146
|
-
const result =
|
|
147
|
-
return { prompt: result, resolvedType: '
|
|
145
|
+
if (id === 'kimi') {
|
|
146
|
+
const result = PROVIDER_KIMI.trim();
|
|
147
|
+
return { prompt: result, resolvedType: 'kimi' };
|
|
148
148
|
}
|
|
149
149
|
if (id === 'zai' || id === 'zai-coding') {
|
|
150
150
|
const result = PROVIDER_GLM.trim();
|
|
@@ -46,7 +46,7 @@ const OWNER_NPM: Record<ModelOwner, string> = {
|
|
|
46
46
|
google: '@ai-sdk/google',
|
|
47
47
|
openrouter: '@openrouter/ai-sdk-provider',
|
|
48
48
|
xai: '@ai-sdk/xai',
|
|
49
|
-
|
|
49
|
+
kimi: '@ai-sdk/openai-compatible',
|
|
50
50
|
qwen: '@ai-sdk/openai-compatible',
|
|
51
51
|
zai: '@ai-sdk/openai-compatible',
|
|
52
52
|
minimax: '@ai-sdk/anthropic',
|
|
@@ -162,21 +162,53 @@ const DEPRECATED_KIMI_MODEL_IDS = new Set([
|
|
|
162
162
|
'kimi-k2-turbo-preview',
|
|
163
163
|
]);
|
|
164
164
|
|
|
165
|
+
const KIMI_MANUAL_MODELS: ModelInfo[] = [
|
|
166
|
+
{
|
|
167
|
+
id: 'kimi-k2.7-code-highspeed',
|
|
168
|
+
ownedBy: 'kimi',
|
|
169
|
+
label: 'Kimi K2.7 Code Highspeed',
|
|
170
|
+
modalities: { input: ['text', 'image', 'video'], output: ['text'] },
|
|
171
|
+
toolCall: true,
|
|
172
|
+
reasoningText: true,
|
|
173
|
+
attachment: true,
|
|
174
|
+
temperature: false,
|
|
175
|
+
knowledge: '2025-01',
|
|
176
|
+
openWeights: true,
|
|
177
|
+
cost: { input: 1.9, output: 8, cacheRead: 0.38 },
|
|
178
|
+
limit: { context: 262_144, output: 262_144 },
|
|
179
|
+
},
|
|
180
|
+
];
|
|
181
|
+
|
|
165
182
|
export function filterAvailableKimiModels(models: ModelInfo[]): ModelInfo[] {
|
|
166
183
|
return models.filter((model) => !DEPRECATED_KIMI_MODEL_IDS.has(model.id));
|
|
167
184
|
}
|
|
168
185
|
|
|
186
|
+
function appendKimiManualModels(models: ModelInfo[]): ModelInfo[] {
|
|
187
|
+
const manualById = new Map(
|
|
188
|
+
KIMI_MANUAL_MODELS.map((model) => [model.id, model]),
|
|
189
|
+
);
|
|
190
|
+
const mergedModels = models.map((model) => {
|
|
191
|
+
const override = manualById.get(model.id);
|
|
192
|
+
return override ? { ...model, ...override } : model;
|
|
193
|
+
});
|
|
194
|
+
const existingIds = new Set(mergedModels.map((model) => model.id));
|
|
195
|
+
const missingModels = KIMI_MANUAL_MODELS.filter(
|
|
196
|
+
(model) => !existingIds.has(model.id),
|
|
197
|
+
);
|
|
198
|
+
return missingModels.length
|
|
199
|
+
? [...mergedModels, ...missingModels]
|
|
200
|
+
: mergedModels;
|
|
201
|
+
}
|
|
202
|
+
|
|
169
203
|
export function applyOfficialKimiCatalogMetadata<
|
|
170
204
|
T extends ProviderCatalogEntry,
|
|
171
205
|
>(entry: T | undefined): T | undefined {
|
|
172
206
|
if (!entry) return undefined;
|
|
173
|
-
const env = Array.from(
|
|
174
|
-
new Set(['KIMI_API_KEY', 'MOONSHOT_API_KEY', ...(entry.env ?? [])]),
|
|
175
|
-
);
|
|
207
|
+
const env = Array.from(new Set(['KIMI_API_KEY', ...(entry.env ?? [])]));
|
|
176
208
|
return {
|
|
177
209
|
...entry,
|
|
178
|
-
models: filterAvailableKimiModels(entry.models),
|
|
179
|
-
label:
|
|
210
|
+
models: appendKimiManualModels(filterAvailableKimiModels(entry.models)),
|
|
211
|
+
label: 'Kimi',
|
|
180
212
|
env,
|
|
181
213
|
doc: 'https://platform.kimi.ai/docs/api/overview.md',
|
|
182
214
|
};
|
|
@@ -195,9 +227,9 @@ export function mergeManualCatalog(
|
|
|
195
227
|
if (xaiEntry) {
|
|
196
228
|
merged.xai = xaiEntry;
|
|
197
229
|
}
|
|
198
|
-
const
|
|
199
|
-
if (
|
|
200
|
-
merged.
|
|
230
|
+
const kimiEntry = applyOfficialKimiCatalogMetadata(merged.kimi);
|
|
231
|
+
if (kimiEntry) {
|
|
232
|
+
merged.kimi = kimiEntry;
|
|
201
233
|
}
|
|
202
234
|
if (manualEntry) {
|
|
203
235
|
merged[OTTOROUTER_ID] = manualEntry;
|
|
@@ -2161,6 +2161,46 @@ export const catalog: Partial<Record<BuiltInProviderId, ProviderCatalogEntry>> =
|
|
|
2161
2161
|
output: 32768,
|
|
2162
2162
|
},
|
|
2163
2163
|
},
|
|
2164
|
+
{
|
|
2165
|
+
id: 'gemma-4-E2B-it',
|
|
2166
|
+
ownedBy: 'google',
|
|
2167
|
+
label: 'Gemma 4 E2B IT',
|
|
2168
|
+
modalities: {
|
|
2169
|
+
input: ['text', 'image', 'audio'],
|
|
2170
|
+
output: ['text'],
|
|
2171
|
+
},
|
|
2172
|
+
toolCall: true,
|
|
2173
|
+
reasoningText: true,
|
|
2174
|
+
attachment: true,
|
|
2175
|
+
temperature: true,
|
|
2176
|
+
releaseDate: '2026-04-02',
|
|
2177
|
+
lastUpdated: '2026-04-02',
|
|
2178
|
+
openWeights: true,
|
|
2179
|
+
limit: {
|
|
2180
|
+
context: 131072,
|
|
2181
|
+
output: 8192,
|
|
2182
|
+
},
|
|
2183
|
+
},
|
|
2184
|
+
{
|
|
2185
|
+
id: 'gemma-4-E4B-it',
|
|
2186
|
+
ownedBy: 'google',
|
|
2187
|
+
label: 'Gemma 4 E4B IT',
|
|
2188
|
+
modalities: {
|
|
2189
|
+
input: ['text', 'image', 'audio'],
|
|
2190
|
+
output: ['text'],
|
|
2191
|
+
},
|
|
2192
|
+
toolCall: true,
|
|
2193
|
+
reasoningText: true,
|
|
2194
|
+
attachment: true,
|
|
2195
|
+
temperature: true,
|
|
2196
|
+
releaseDate: '2026-04-02',
|
|
2197
|
+
lastUpdated: '2026-04-02',
|
|
2198
|
+
openWeights: true,
|
|
2199
|
+
limit: {
|
|
2200
|
+
context: 131072,
|
|
2201
|
+
output: 8192,
|
|
2202
|
+
},
|
|
2203
|
+
},
|
|
2164
2204
|
],
|
|
2165
2205
|
label: 'Google',
|
|
2166
2206
|
env: ['GOOGLE_API_KEY', 'GOOGLE_GENERATIVE_AI_API_KEY', 'GEMINI_API_KEY'],
|
|
@@ -2329,8 +2369,8 @@ export const catalog: Partial<Record<BuiltInProviderId, ProviderCatalogEntry>> =
|
|
|
2329
2369
|
},
|
|
2330
2370
|
{
|
|
2331
2371
|
id: '~moonshotai/kimi-latest',
|
|
2332
|
-
ownedBy: '
|
|
2333
|
-
label: '
|
|
2372
|
+
ownedBy: 'kimi',
|
|
2373
|
+
label: 'Kimi Latest',
|
|
2334
2374
|
modalities: {
|
|
2335
2375
|
input: ['text', 'image'],
|
|
2336
2376
|
output: ['text'],
|
|
@@ -3398,13 +3438,13 @@ export const catalog: Partial<Record<BuiltInProviderId, ProviderCatalogEntry>> =
|
|
|
3398
3438
|
lastUpdated: '2026-04-24',
|
|
3399
3439
|
openWeights: true,
|
|
3400
3440
|
cost: {
|
|
3401
|
-
input: 0.
|
|
3402
|
-
output: 0.
|
|
3441
|
+
input: 0.09,
|
|
3442
|
+
output: 0.18,
|
|
3403
3443
|
cacheRead: 0.02,
|
|
3404
3444
|
},
|
|
3405
3445
|
limit: {
|
|
3406
|
-
context:
|
|
3407
|
-
output:
|
|
3446
|
+
context: 1000000,
|
|
3447
|
+
output: 65536,
|
|
3408
3448
|
},
|
|
3409
3449
|
},
|
|
3410
3450
|
{
|
|
@@ -4353,7 +4393,7 @@ export const catalog: Partial<Record<BuiltInProviderId, ProviderCatalogEntry>> =
|
|
|
4353
4393
|
temperature: true,
|
|
4354
4394
|
releaseDate: '2026-06-01',
|
|
4355
4395
|
lastUpdated: '2026-06-01',
|
|
4356
|
-
openWeights:
|
|
4396
|
+
openWeights: true,
|
|
4357
4397
|
cost: {
|
|
4358
4398
|
input: 0.3,
|
|
4359
4399
|
output: 1.2,
|
|
@@ -4783,7 +4823,7 @@ export const catalog: Partial<Record<BuiltInProviderId, ProviderCatalogEntry>> =
|
|
|
4783
4823
|
},
|
|
4784
4824
|
{
|
|
4785
4825
|
id: 'moonshotai/kimi-k2',
|
|
4786
|
-
ownedBy: '
|
|
4826
|
+
ownedBy: 'kimi',
|
|
4787
4827
|
label: 'Kimi K2 0711',
|
|
4788
4828
|
modalities: {
|
|
4789
4829
|
input: ['text'],
|
|
@@ -4808,7 +4848,7 @@ export const catalog: Partial<Record<BuiltInProviderId, ProviderCatalogEntry>> =
|
|
|
4808
4848
|
},
|
|
4809
4849
|
{
|
|
4810
4850
|
id: 'moonshotai/kimi-k2-0905',
|
|
4811
|
-
ownedBy: '
|
|
4851
|
+
ownedBy: 'kimi',
|
|
4812
4852
|
label: 'Kimi K2 0905',
|
|
4813
4853
|
modalities: {
|
|
4814
4854
|
input: ['text'],
|
|
@@ -4833,7 +4873,7 @@ export const catalog: Partial<Record<BuiltInProviderId, ProviderCatalogEntry>> =
|
|
|
4833
4873
|
},
|
|
4834
4874
|
{
|
|
4835
4875
|
id: 'moonshotai/kimi-k2-thinking',
|
|
4836
|
-
ownedBy: '
|
|
4876
|
+
ownedBy: 'kimi',
|
|
4837
4877
|
label: 'Kimi K2 Thinking',
|
|
4838
4878
|
modalities: {
|
|
4839
4879
|
input: ['text'],
|
|
@@ -4858,7 +4898,7 @@ export const catalog: Partial<Record<BuiltInProviderId, ProviderCatalogEntry>> =
|
|
|
4858
4898
|
},
|
|
4859
4899
|
{
|
|
4860
4900
|
id: 'moonshotai/kimi-k2.5',
|
|
4861
|
-
ownedBy: '
|
|
4901
|
+
ownedBy: 'kimi',
|
|
4862
4902
|
label: 'Kimi K2.5',
|
|
4863
4903
|
modalities: {
|
|
4864
4904
|
input: ['text', 'image'],
|
|
@@ -4883,7 +4923,7 @@ export const catalog: Partial<Record<BuiltInProviderId, ProviderCatalogEntry>> =
|
|
|
4883
4923
|
},
|
|
4884
4924
|
{
|
|
4885
4925
|
id: 'moonshotai/kimi-k2.6',
|
|
4886
|
-
ownedBy: '
|
|
4926
|
+
ownedBy: 'kimi',
|
|
4887
4927
|
label: 'Kimi K2.6',
|
|
4888
4928
|
modalities: {
|
|
4889
4929
|
input: ['text', 'image'],
|
|
@@ -4909,7 +4949,7 @@ export const catalog: Partial<Record<BuiltInProviderId, ProviderCatalogEntry>> =
|
|
|
4909
4949
|
},
|
|
4910
4950
|
{
|
|
4911
4951
|
id: 'moonshotai/kimi-k2.7-code',
|
|
4912
|
-
ownedBy: '
|
|
4952
|
+
ownedBy: 'kimi',
|
|
4913
4953
|
label: 'Kimi K2.7 Code',
|
|
4914
4954
|
modalities: {
|
|
4915
4955
|
input: ['text', 'image'],
|
|
@@ -9722,7 +9762,7 @@ export const catalog: Partial<Record<BuiltInProviderId, ProviderCatalogEntry>> =
|
|
|
9722
9762
|
},
|
|
9723
9763
|
{
|
|
9724
9764
|
id: 'kimi-k2',
|
|
9725
|
-
ownedBy: '
|
|
9765
|
+
ownedBy: 'kimi',
|
|
9726
9766
|
label: 'Kimi K2',
|
|
9727
9767
|
modalities: {
|
|
9728
9768
|
input: ['text'],
|
|
@@ -9748,7 +9788,7 @@ export const catalog: Partial<Record<BuiltInProviderId, ProviderCatalogEntry>> =
|
|
|
9748
9788
|
},
|
|
9749
9789
|
{
|
|
9750
9790
|
id: 'kimi-k2-thinking',
|
|
9751
|
-
ownedBy: '
|
|
9791
|
+
ownedBy: 'kimi',
|
|
9752
9792
|
label: 'Kimi K2 Thinking',
|
|
9753
9793
|
modalities: {
|
|
9754
9794
|
input: ['text'],
|
|
@@ -9774,7 +9814,7 @@ export const catalog: Partial<Record<BuiltInProviderId, ProviderCatalogEntry>> =
|
|
|
9774
9814
|
},
|
|
9775
9815
|
{
|
|
9776
9816
|
id: 'kimi-k2.5',
|
|
9777
|
-
ownedBy: '
|
|
9817
|
+
ownedBy: 'kimi',
|
|
9778
9818
|
label: 'Kimi K2.5',
|
|
9779
9819
|
modalities: {
|
|
9780
9820
|
input: ['text', 'image', 'video'],
|
|
@@ -9800,7 +9840,7 @@ export const catalog: Partial<Record<BuiltInProviderId, ProviderCatalogEntry>> =
|
|
|
9800
9840
|
},
|
|
9801
9841
|
{
|
|
9802
9842
|
id: 'kimi-k2.5-free',
|
|
9803
|
-
ownedBy: '
|
|
9843
|
+
ownedBy: 'kimi',
|
|
9804
9844
|
label: 'Kimi K2.5 Free',
|
|
9805
9845
|
modalities: {
|
|
9806
9846
|
input: ['text', 'image', 'video'],
|
|
@@ -9826,7 +9866,7 @@ export const catalog: Partial<Record<BuiltInProviderId, ProviderCatalogEntry>> =
|
|
|
9826
9866
|
},
|
|
9827
9867
|
{
|
|
9828
9868
|
id: 'kimi-k2.6',
|
|
9829
|
-
ownedBy: '
|
|
9869
|
+
ownedBy: 'kimi',
|
|
9830
9870
|
label: 'Kimi K2.6',
|
|
9831
9871
|
modalities: {
|
|
9832
9872
|
input: ['text', 'image', 'video'],
|
|
@@ -11008,12 +11048,12 @@ export const catalog: Partial<Record<BuiltInProviderId, ProviderCatalogEntry>> =
|
|
|
11008
11048
|
api: 'https://api.z.ai/api/coding/paas/v4',
|
|
11009
11049
|
doc: 'https://docs.z.ai/devpack/overview',
|
|
11010
11050
|
},
|
|
11011
|
-
|
|
11012
|
-
id: '
|
|
11051
|
+
kimi: {
|
|
11052
|
+
id: 'kimi',
|
|
11013
11053
|
models: [
|
|
11014
11054
|
{
|
|
11015
11055
|
id: 'kimi-k2-0711-preview',
|
|
11016
|
-
ownedBy: '
|
|
11056
|
+
ownedBy: 'kimi',
|
|
11017
11057
|
label: 'Kimi K2 0711',
|
|
11018
11058
|
modalities: {
|
|
11019
11059
|
input: ['text'],
|
|
@@ -11039,7 +11079,7 @@ export const catalog: Partial<Record<BuiltInProviderId, ProviderCatalogEntry>> =
|
|
|
11039
11079
|
},
|
|
11040
11080
|
{
|
|
11041
11081
|
id: 'kimi-k2-0905-preview',
|
|
11042
|
-
ownedBy: '
|
|
11082
|
+
ownedBy: 'kimi',
|
|
11043
11083
|
label: 'Kimi K2 0905',
|
|
11044
11084
|
modalities: {
|
|
11045
11085
|
input: ['text'],
|
|
@@ -11065,7 +11105,7 @@ export const catalog: Partial<Record<BuiltInProviderId, ProviderCatalogEntry>> =
|
|
|
11065
11105
|
},
|
|
11066
11106
|
{
|
|
11067
11107
|
id: 'kimi-k2-thinking',
|
|
11068
|
-
ownedBy: '
|
|
11108
|
+
ownedBy: 'kimi',
|
|
11069
11109
|
label: 'Kimi K2 Thinking',
|
|
11070
11110
|
modalities: {
|
|
11071
11111
|
input: ['text'],
|
|
@@ -11091,7 +11131,7 @@ export const catalog: Partial<Record<BuiltInProviderId, ProviderCatalogEntry>> =
|
|
|
11091
11131
|
},
|
|
11092
11132
|
{
|
|
11093
11133
|
id: 'kimi-k2-thinking-turbo',
|
|
11094
|
-
ownedBy: '
|
|
11134
|
+
ownedBy: 'kimi',
|
|
11095
11135
|
label: 'Kimi K2 Thinking Turbo',
|
|
11096
11136
|
modalities: {
|
|
11097
11137
|
input: ['text'],
|
|
@@ -11117,7 +11157,7 @@ export const catalog: Partial<Record<BuiltInProviderId, ProviderCatalogEntry>> =
|
|
|
11117
11157
|
},
|
|
11118
11158
|
{
|
|
11119
11159
|
id: 'kimi-k2-turbo-preview',
|
|
11120
|
-
ownedBy: '
|
|
11160
|
+
ownedBy: 'kimi',
|
|
11121
11161
|
label: 'Kimi K2 Turbo',
|
|
11122
11162
|
modalities: {
|
|
11123
11163
|
input: ['text'],
|
|
@@ -11143,7 +11183,7 @@ export const catalog: Partial<Record<BuiltInProviderId, ProviderCatalogEntry>> =
|
|
|
11143
11183
|
},
|
|
11144
11184
|
{
|
|
11145
11185
|
id: 'kimi-k2.5',
|
|
11146
|
-
ownedBy: '
|
|
11186
|
+
ownedBy: 'kimi',
|
|
11147
11187
|
label: 'Kimi K2.5',
|
|
11148
11188
|
modalities: {
|
|
11149
11189
|
input: ['text', 'image', 'video'],
|
|
@@ -11169,7 +11209,7 @@ export const catalog: Partial<Record<BuiltInProviderId, ProviderCatalogEntry>> =
|
|
|
11169
11209
|
},
|
|
11170
11210
|
{
|
|
11171
11211
|
id: 'kimi-k2.6',
|
|
11172
|
-
ownedBy: '
|
|
11212
|
+
ownedBy: 'kimi',
|
|
11173
11213
|
label: 'Kimi K2.6',
|
|
11174
11214
|
modalities: {
|
|
11175
11215
|
input: ['text', 'image', 'video'],
|
|
@@ -11195,7 +11235,7 @@ export const catalog: Partial<Record<BuiltInProviderId, ProviderCatalogEntry>> =
|
|
|
11195
11235
|
},
|
|
11196
11236
|
{
|
|
11197
11237
|
id: 'kimi-k2.7-code',
|
|
11198
|
-
ownedBy: '
|
|
11238
|
+
ownedBy: 'kimi',
|
|
11199
11239
|
label: 'Kimi K2.7 Code',
|
|
11200
11240
|
modalities: {
|
|
11201
11241
|
input: ['text', 'image', 'video'],
|
|
@@ -11221,7 +11261,7 @@ export const catalog: Partial<Record<BuiltInProviderId, ProviderCatalogEntry>> =
|
|
|
11221
11261
|
},
|
|
11222
11262
|
],
|
|
11223
11263
|
label: 'Kimi',
|
|
11224
|
-
env: ['KIMI_API_KEY'
|
|
11264
|
+
env: ['KIMI_API_KEY'],
|
|
11225
11265
|
npm: '@ai-sdk/openai-compatible',
|
|
11226
11266
|
api: 'https://api.moonshot.ai/v1',
|
|
11227
11267
|
doc: 'https://platform.kimi.ai/docs/api/overview.md',
|
|
@@ -12313,7 +12353,7 @@ export const catalog: Partial<Record<BuiltInProviderId, ProviderCatalogEntry>> =
|
|
|
12313
12353
|
},
|
|
12314
12354
|
{
|
|
12315
12355
|
id: 'kimi-k2-thinking',
|
|
12316
|
-
ownedBy: '
|
|
12356
|
+
ownedBy: 'kimi',
|
|
12317
12357
|
label: 'kimi-k2-thinking',
|
|
12318
12358
|
modalities: {
|
|
12319
12359
|
input: ['text'],
|
|
@@ -12333,7 +12373,7 @@ export const catalog: Partial<Record<BuiltInProviderId, ProviderCatalogEntry>> =
|
|
|
12333
12373
|
},
|
|
12334
12374
|
{
|
|
12335
12375
|
id: 'kimi-k2:1t',
|
|
12336
|
-
ownedBy: '
|
|
12376
|
+
ownedBy: 'kimi',
|
|
12337
12377
|
label: 'kimi-k2:1t',
|
|
12338
12378
|
modalities: {
|
|
12339
12379
|
input: ['text'],
|
|
@@ -12353,7 +12393,7 @@ export const catalog: Partial<Record<BuiltInProviderId, ProviderCatalogEntry>> =
|
|
|
12353
12393
|
},
|
|
12354
12394
|
{
|
|
12355
12395
|
id: 'kimi-k2.5',
|
|
12356
|
-
ownedBy: '
|
|
12396
|
+
ownedBy: 'kimi',
|
|
12357
12397
|
label: 'kimi-k2.5',
|
|
12358
12398
|
modalities: {
|
|
12359
12399
|
input: ['text', 'image'],
|
|
@@ -12372,7 +12412,7 @@ export const catalog: Partial<Record<BuiltInProviderId, ProviderCatalogEntry>> =
|
|
|
12372
12412
|
},
|
|
12373
12413
|
{
|
|
12374
12414
|
id: 'kimi-k2.6',
|
|
12375
|
-
ownedBy: '
|
|
12415
|
+
ownedBy: 'kimi',
|
|
12376
12416
|
label: 'kimi-k2.6',
|
|
12377
12417
|
modalities: {
|
|
12378
12418
|
input: ['text', 'image'],
|
|
@@ -12391,7 +12431,7 @@ export const catalog: Partial<Record<BuiltInProviderId, ProviderCatalogEntry>> =
|
|
|
12391
12431
|
},
|
|
12392
12432
|
{
|
|
12393
12433
|
id: 'kimi-k2.7-code',
|
|
12394
|
-
ownedBy: '
|
|
12434
|
+
ownedBy: 'kimi',
|
|
12395
12435
|
label: 'kimi-k2.7-code',
|
|
12396
12436
|
modalities: {
|
|
12397
12437
|
input: ['text', 'image'],
|
package/src/providers/src/env.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { BuiltInProviderId, ProviderId } from '../../types/src/index.ts';
|
|
2
|
-
import { readKimiApiKeyFromEnv } from './
|
|
2
|
+
import { readKimiApiKeyFromEnv } from './kimi-client.ts';
|
|
3
3
|
|
|
4
4
|
const ENV_VARS: Record<BuiltInProviderId, string> = {
|
|
5
5
|
openai: 'OPENAI_API_KEY',
|
|
@@ -13,19 +13,16 @@ const ENV_VARS: Record<BuiltInProviderId, string> = {
|
|
|
13
13
|
xai: 'XAI_API_KEY',
|
|
14
14
|
zai: 'ZAI_API_KEY',
|
|
15
15
|
'zai-coding': 'ZAI_CODING_API_KEY',
|
|
16
|
-
|
|
16
|
+
kimi: 'KIMI_API_KEY',
|
|
17
17
|
minimax: 'MINIMAX_API_KEY',
|
|
18
18
|
};
|
|
19
19
|
|
|
20
|
-
const KIMI_PROVIDER_IDS = new Set<ProviderId>(['kimi', 'moonshot']);
|
|
21
|
-
|
|
22
20
|
export function providerEnvVar(provider: ProviderId): string | undefined {
|
|
23
|
-
if (provider === 'kimi') return 'KIMI_API_KEY';
|
|
24
21
|
return ENV_VARS[provider as BuiltInProviderId];
|
|
25
22
|
}
|
|
26
23
|
|
|
27
24
|
export function readEnvKey(provider: ProviderId): string | undefined {
|
|
28
|
-
if (
|
|
25
|
+
if (provider === 'kimi') {
|
|
29
26
|
const value = readKimiApiKeyFromEnv();
|
|
30
27
|
return value.length ? value : undefined;
|
|
31
28
|
}
|
|
@@ -48,7 +45,7 @@ export function readEnvKey(provider: ProviderId): string | undefined {
|
|
|
48
45
|
|
|
49
46
|
export function setEnvKey(provider: ProviderId, value: string | undefined) {
|
|
50
47
|
if (!value) return;
|
|
51
|
-
if (
|
|
48
|
+
if (provider === 'kimi') {
|
|
52
49
|
process.env.KIMI_API_KEY = value;
|
|
53
50
|
return;
|
|
54
51
|
}
|
|
@@ -52,6 +52,7 @@ export type {
|
|
|
52
52
|
} from './ollama-discovery.ts';
|
|
53
53
|
export {
|
|
54
54
|
isBuiltInProviderId,
|
|
55
|
+
resolveBuiltInProviderCatalogId,
|
|
55
56
|
getProviderSettings,
|
|
56
57
|
getProviderDefinition,
|
|
57
58
|
hasConfiguredProvider,
|
|
@@ -123,15 +124,8 @@ export {
|
|
|
123
124
|
export type { OpenRouterProviderConfig } from './openrouter-client.ts';
|
|
124
125
|
export { createOpencodeModel } from './opencode-client.ts';
|
|
125
126
|
export type { OpencodeProviderConfig } from './opencode-client.ts';
|
|
126
|
-
export {
|
|
127
|
-
|
|
128
|
-
createMoonshotModel,
|
|
129
|
-
readKimiApiKeyFromEnv,
|
|
130
|
-
} from './moonshot-client.ts';
|
|
131
|
-
export type {
|
|
132
|
-
KimiProviderConfig,
|
|
133
|
-
MoonshotProviderConfig,
|
|
134
|
-
} from './moonshot-client.ts';
|
|
127
|
+
export { createKimiModel, readKimiApiKeyFromEnv } from './kimi-client.ts';
|
|
128
|
+
export type { KimiProviderConfig } from './kimi-client.ts';
|
|
135
129
|
export { createMinimaxModel } from './minimax-client.ts';
|
|
136
130
|
export type { MinimaxProviderConfig } from './minimax-client.ts';
|
|
137
131
|
export { createCopilotFetch, createCopilotModel } from './copilot-client.ts';
|
|
@@ -8,15 +8,139 @@ export type KimiProviderConfig = {
|
|
|
8
8
|
oauth?: OAuth;
|
|
9
9
|
};
|
|
10
10
|
|
|
11
|
-
/** @deprecated Use `KimiProviderConfig` */
|
|
12
|
-
export type MoonshotProviderConfig = KimiProviderConfig;
|
|
13
|
-
|
|
14
11
|
export function readKimiApiKeyFromEnv(): string {
|
|
15
|
-
return process.env.KIMI_API_KEY ||
|
|
12
|
+
return process.env.KIMI_API_KEY || '';
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const KIMI_UNSUPPORTED_SCHEMA_KEYS = new Set([
|
|
16
|
+
'$schema',
|
|
17
|
+
'$id',
|
|
18
|
+
'$ref',
|
|
19
|
+
'$defs',
|
|
20
|
+
'definitions',
|
|
21
|
+
'examples',
|
|
22
|
+
'title',
|
|
23
|
+
'nullable',
|
|
24
|
+
'format',
|
|
25
|
+
'pattern',
|
|
26
|
+
'minLength',
|
|
27
|
+
'maxLength',
|
|
28
|
+
'minimum',
|
|
29
|
+
'maximum',
|
|
30
|
+
'exclusiveMinimum',
|
|
31
|
+
'exclusiveMaximum',
|
|
32
|
+
'multipleOf',
|
|
33
|
+
'minItems',
|
|
34
|
+
'maxItems',
|
|
35
|
+
'uniqueItems',
|
|
36
|
+
'contains',
|
|
37
|
+
'minContains',
|
|
38
|
+
'maxContains',
|
|
39
|
+
'prefixItems',
|
|
40
|
+
'propertyNames',
|
|
41
|
+
'patternProperties',
|
|
42
|
+
'allOf',
|
|
43
|
+
'not',
|
|
44
|
+
'if',
|
|
45
|
+
'then',
|
|
46
|
+
'else',
|
|
47
|
+
'dependentSchemas',
|
|
48
|
+
'dependentRequired',
|
|
49
|
+
'unevaluatedProperties',
|
|
50
|
+
]);
|
|
51
|
+
|
|
52
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
53
|
+
return Boolean(value && typeof value === 'object' && !Array.isArray(value));
|
|
16
54
|
}
|
|
17
55
|
|
|
18
56
|
/**
|
|
19
|
-
*
|
|
57
|
+
* Converts AI SDK JSON Schema output into the smaller schema dialect accepted
|
|
58
|
+
* by Kimi tool calls.
|
|
59
|
+
*/
|
|
60
|
+
export function sanitizeKimiToolSchema(schema: unknown): unknown {
|
|
61
|
+
if (Array.isArray(schema))
|
|
62
|
+
return schema.map((item) => sanitizeKimiToolSchema(item));
|
|
63
|
+
if (!isRecord(schema)) return schema;
|
|
64
|
+
|
|
65
|
+
const out: Record<string, unknown> = {};
|
|
66
|
+
|
|
67
|
+
for (const [key, value] of Object.entries(schema)) {
|
|
68
|
+
if (key === 'const') {
|
|
69
|
+
if (['number', 'string'].includes(typeof value)) out.enum = [value];
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
if (key === 'oneOf') {
|
|
73
|
+
const branches = toArray(value);
|
|
74
|
+
if (branches.length > 0) out.anyOf = sanitizeKimiToolSchema(branches);
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
if (key === 'properties' && isRecord(value)) {
|
|
78
|
+
out.properties = Object.fromEntries(
|
|
79
|
+
Object.entries(value).map(([propertyName, propertySchema]) => [
|
|
80
|
+
propertyName,
|
|
81
|
+
sanitizeKimiToolSchema(propertySchema),
|
|
82
|
+
]),
|
|
83
|
+
);
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
if (KIMI_UNSUPPORTED_SCHEMA_KEYS.has(key)) continue;
|
|
87
|
+
if (key === 'type' && Array.isArray(value)) {
|
|
88
|
+
const types = value.filter(
|
|
89
|
+
(type): type is string => typeof type === 'string',
|
|
90
|
+
);
|
|
91
|
+
if (types.length === 1) out.type = types[0];
|
|
92
|
+
else if (types.length > 1) {
|
|
93
|
+
out.anyOf = types.map((type) => ({ type }));
|
|
94
|
+
}
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
if (key === 'enum' && Array.isArray(value)) {
|
|
98
|
+
out.enum = value.filter((item) => item !== null);
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
out[key] = sanitizeKimiToolSchema(value);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return out;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function toArray(value: unknown): unknown[] {
|
|
108
|
+
return Array.isArray(value) ? value : [];
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function sanitizeKimiToolRequest(body: unknown): unknown {
|
|
112
|
+
if (!isRecord(body) || !Array.isArray(body.tools)) return body;
|
|
113
|
+
let changed = false;
|
|
114
|
+
const tools = body.tools.map((tool) => {
|
|
115
|
+
if (!isRecord(tool)) return tool;
|
|
116
|
+
const fn = tool.function;
|
|
117
|
+
if (!isRecord(fn) || !('parameters' in fn)) return tool;
|
|
118
|
+
changed = true;
|
|
119
|
+
return {
|
|
120
|
+
...tool,
|
|
121
|
+
function: {
|
|
122
|
+
...fn,
|
|
123
|
+
parameters: sanitizeKimiToolSchema(fn.parameters),
|
|
124
|
+
},
|
|
125
|
+
};
|
|
126
|
+
});
|
|
127
|
+
return changed ? { ...body, tools } : body;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function sanitizeKimiFetchInit(init?: RequestInit): RequestInit | undefined {
|
|
131
|
+
if (!init || typeof init.body !== 'string') return init;
|
|
132
|
+
try {
|
|
133
|
+
const parsed = JSON.parse(init.body) as unknown;
|
|
134
|
+
const sanitized = sanitizeKimiToolRequest(parsed);
|
|
135
|
+
if (sanitized === parsed) return init;
|
|
136
|
+
return { ...init, body: JSON.stringify(sanitized) };
|
|
137
|
+
} catch {
|
|
138
|
+
return init;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Kimi streaming responses report token usage on the final chunk's
|
|
20
144
|
* `choices[0].usage` instead of the OpenAI-standard top-level `usage` field.
|
|
21
145
|
* The AI SDK openai-compatible parser only reads top-level `usage`, so we
|
|
22
146
|
* hoist choice-level usage to the top level when it is missing.
|
|
@@ -57,7 +181,7 @@ export function createKimiUsageFetch(
|
|
|
57
181
|
input: Parameters<typeof fetch>[0],
|
|
58
182
|
init?: Parameters<typeof fetch>[1],
|
|
59
183
|
): Promise<Response> => {
|
|
60
|
-
const response = await baseFetch(input, init);
|
|
184
|
+
const response = await baseFetch(input, sanitizeKimiFetchInit(init));
|
|
61
185
|
const contentType = response.headers.get('content-type') ?? '';
|
|
62
186
|
if (
|
|
63
187
|
!response.ok ||
|
|
@@ -100,7 +224,7 @@ export function createKimiUsageFetch(
|
|
|
100
224
|
}
|
|
101
225
|
|
|
102
226
|
export function createKimiModel(model: string, config?: KimiProviderConfig) {
|
|
103
|
-
const entry = catalog.
|
|
227
|
+
const entry = catalog.kimi;
|
|
104
228
|
const oauthAccess = config?.oauth?.access;
|
|
105
229
|
const defaultApiBaseURL = entry?.api ?? 'https://api.moonshot.ai/v1';
|
|
106
230
|
const configuredBaseURL = config?.baseURL;
|
|
@@ -123,11 +247,3 @@ export function createKimiModel(model: string, config?: KimiProviderConfig) {
|
|
|
123
247
|
|
|
124
248
|
return instance(model);
|
|
125
249
|
}
|
|
126
|
-
|
|
127
|
-
/** @deprecated Use `createKimiModel` */
|
|
128
|
-
export function createMoonshotModel(
|
|
129
|
-
model: string,
|
|
130
|
-
config?: MoonshotProviderConfig,
|
|
131
|
-
) {
|
|
132
|
-
return createKimiModel(model, config);
|
|
133
|
-
}
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import type { ModelInfo } from '../../types/src/index.ts';
|
|
2
2
|
|
|
3
|
+
function normalizeModelInfo(model: ModelInfo): ModelInfo {
|
|
4
|
+
return (model.ownedBy as string | undefined) === 'moonshot'
|
|
5
|
+
? { ...model, ownedBy: 'kimi' }
|
|
6
|
+
: model;
|
|
7
|
+
}
|
|
8
|
+
|
|
3
9
|
/**
|
|
4
10
|
* Merge embedded/manual catalog models with cached (remote/local) models by id.
|
|
5
11
|
*
|
|
@@ -13,7 +19,7 @@ export function mergeModelLists(
|
|
|
13
19
|
cachedModels: ModelInfo[] | undefined,
|
|
14
20
|
): ModelInfo[] {
|
|
15
21
|
const base = baseModels ?? [];
|
|
16
|
-
const cached = cachedModels ?? [];
|
|
22
|
+
const cached = (cachedModels ?? []).map(normalizeModelInfo);
|
|
17
23
|
if (!cached.length) return base;
|
|
18
24
|
if (!base.length) return cached;
|
|
19
25
|
const cachedById = new Map(cached.map((model) => [model.id, model]));
|
|
@@ -39,7 +39,7 @@ const BUILTIN_COMPATIBILITY: Record<BuiltInProviderId, ProviderCompatibility> =
|
|
|
39
39
|
xai: 'openai',
|
|
40
40
|
zai: 'openai-compatible',
|
|
41
41
|
'zai-coding': 'openai-compatible',
|
|
42
|
-
|
|
42
|
+
kimi: 'openai-compatible',
|
|
43
43
|
minimax: 'anthropic',
|
|
44
44
|
};
|
|
45
45
|
|
|
@@ -55,7 +55,7 @@ const BUILTIN_FAMILY: Record<BuiltInProviderId, ProviderPromptFamily> = {
|
|
|
55
55
|
xai: 'openai',
|
|
56
56
|
zai: 'glm',
|
|
57
57
|
'zai-coding': 'glm',
|
|
58
|
-
|
|
58
|
+
kimi: 'kimi',
|
|
59
59
|
minimax: 'minimax',
|
|
60
60
|
};
|
|
61
61
|
function normalizeOptionalText(value: string | undefined): string | undefined {
|
|
@@ -95,8 +95,6 @@ function resolveCustomFamily(
|
|
|
95
95
|
return settings.family ?? 'default';
|
|
96
96
|
}
|
|
97
97
|
|
|
98
|
-
export const KIMI_PROVIDER_ALIAS = 'kimi' as const;
|
|
99
|
-
|
|
100
98
|
function isCatalogBuiltInProviderId(
|
|
101
99
|
value: unknown,
|
|
102
100
|
): value is BuiltInProviderId {
|
|
@@ -109,7 +107,6 @@ function isCatalogBuiltInProviderId(
|
|
|
109
107
|
export function resolveBuiltInProviderCatalogId(
|
|
110
108
|
provider: ProviderId,
|
|
111
109
|
): BuiltInProviderId | undefined {
|
|
112
|
-
if (provider === KIMI_PROVIDER_ALIAS) return 'moonshot';
|
|
113
110
|
if (isCatalogBuiltInProviderId(provider)) return provider;
|
|
114
111
|
return undefined;
|
|
115
112
|
}
|
|
@@ -117,7 +114,7 @@ export function resolveBuiltInProviderCatalogId(
|
|
|
117
114
|
export function isBuiltInProviderId(
|
|
118
115
|
value: unknown,
|
|
119
116
|
): value is BuiltInProviderId {
|
|
120
|
-
return isCatalogBuiltInProviderId(value)
|
|
117
|
+
return isCatalogBuiltInProviderId(value);
|
|
121
118
|
}
|
|
122
119
|
|
|
123
120
|
export function getProviderSettings(
|
|
@@ -138,21 +135,14 @@ export function getProviderDefinition(
|
|
|
138
135
|
if (!entry) return undefined;
|
|
139
136
|
const cachedEntry = getCachedProviderCatalogEntry(catalogProvider);
|
|
140
137
|
const models = mergeModelLists(entry.models, cachedEntry?.models);
|
|
141
|
-
const
|
|
142
|
-
provider === KIMI_PROVIDER_ALIAS
|
|
143
|
-
? (getProviderSettings(cfg, 'moonshot') ?? settings)
|
|
144
|
-
: settings;
|
|
145
|
-
const resolvedSettings =
|
|
146
|
-
provider === KIMI_PROVIDER_ALIAS
|
|
147
|
-
? (settings ?? moonshotSettings)
|
|
148
|
-
: settings;
|
|
138
|
+
const resolvedSettings = settings;
|
|
149
139
|
return {
|
|
150
140
|
id: provider,
|
|
151
141
|
label:
|
|
152
142
|
resolvedSettings?.label ??
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
143
|
+
cachedEntry?.label ??
|
|
144
|
+
entry.label ??
|
|
145
|
+
provider,
|
|
156
146
|
source: 'built-in',
|
|
157
147
|
compatibility: BUILTIN_COMPATIBILITY[catalogProvider],
|
|
158
148
|
family: BUILTIN_FAMILY[catalogProvider],
|
|
@@ -202,7 +192,6 @@ export function getConfiguredProviderIds(
|
|
|
202
192
|
const includeDisabled = options?.includeDisabled === true;
|
|
203
193
|
const ids = new Set<ProviderId>([
|
|
204
194
|
...providerIds,
|
|
205
|
-
KIMI_PROVIDER_ALIAS,
|
|
206
195
|
...Object.keys(cfg.providers),
|
|
207
196
|
cfg.defaults.provider,
|
|
208
197
|
]);
|
|
@@ -280,7 +269,7 @@ export function getConfiguredProviderApiKey(
|
|
|
280
269
|
const definition = getProviderDefinition(cfg, provider);
|
|
281
270
|
if (!definition) return undefined;
|
|
282
271
|
if (definition.apiKey?.length) return definition.apiKey;
|
|
283
|
-
if (provider ===
|
|
272
|
+
if (provider === 'kimi') {
|
|
284
273
|
const envValue = readEnvKey(provider);
|
|
285
274
|
if (envValue?.length) return envValue;
|
|
286
275
|
}
|
|
@@ -46,13 +46,13 @@ const PREFERRED_FAST_MODELS: Partial<Record<ProviderId, string[]>> = {
|
|
|
46
46
|
xai: ['grok-code-fast-1', 'grok-4-fast'],
|
|
47
47
|
zai: ['glm-4.5-flash'],
|
|
48
48
|
copilot: ['gpt-4.1-mini'],
|
|
49
|
-
|
|
49
|
+
kimi: ['kimi-k2.7-code'],
|
|
50
50
|
};
|
|
51
51
|
|
|
52
52
|
const PREFERRED_FAST_MODELS_OAUTH: Partial<Record<ProviderId, string[]>> = {
|
|
53
53
|
openai: ['gpt-5.4-mini'],
|
|
54
54
|
anthropic: ['claude-haiku-4-5'],
|
|
55
|
-
|
|
55
|
+
kimi: ['kimi-k2.7-code'],
|
|
56
56
|
};
|
|
57
57
|
|
|
58
58
|
function preferredFastModelKey(provider: ProviderId): ProviderId {
|
|
@@ -148,7 +148,7 @@ const OWNER_TO_FAMILY: Record<ModelOwner, UnderlyingProviderKey> = {
|
|
|
148
148
|
google: 'google',
|
|
149
149
|
openrouter: 'openai-compatible',
|
|
150
150
|
xai: 'openai',
|
|
151
|
-
|
|
151
|
+
kimi: 'kimi',
|
|
152
152
|
qwen: 'openai-compatible',
|
|
153
153
|
zai: 'glm',
|
|
154
154
|
minimax: 'minimax',
|
|
@@ -161,7 +161,7 @@ const DIRECT_PROVIDER_FAMILY: Partial<
|
|
|
161
161
|
anthropic: 'anthropic',
|
|
162
162
|
google: 'google',
|
|
163
163
|
'ollama-cloud': 'openai-compatible',
|
|
164
|
-
|
|
164
|
+
kimi: 'kimi',
|
|
165
165
|
minimax: 'minimax',
|
|
166
166
|
copilot: 'openai',
|
|
167
167
|
xai: 'openai',
|
|
@@ -173,7 +173,7 @@ export type UnderlyingProviderKey =
|
|
|
173
173
|
| 'anthropic'
|
|
174
174
|
| 'openai'
|
|
175
175
|
| 'google'
|
|
176
|
-
| '
|
|
176
|
+
| 'kimi'
|
|
177
177
|
| 'minimax'
|
|
178
178
|
| 'glm'
|
|
179
179
|
| 'openai-compatible'
|
|
@@ -193,8 +193,7 @@ function inferFromModelId(model: string): UnderlyingProviderKey {
|
|
|
193
193
|
if (lower.includes('grok') || lower.startsWith('xai/')) return 'openai';
|
|
194
194
|
if (lower.includes('qwen') || lower.startsWith('qwen/'))
|
|
195
195
|
return 'openai-compatible';
|
|
196
|
-
if (lower.includes('kimi') || lower.startsWith('moonshotai/'))
|
|
197
|
-
return 'moonshot';
|
|
196
|
+
if (lower.includes('kimi') || lower.startsWith('moonshotai/')) return 'kimi';
|
|
198
197
|
if (
|
|
199
198
|
lower.includes('glm') ||
|
|
200
199
|
lower.startsWith('z-ai/') ||
|
|
@@ -265,7 +264,7 @@ function getProviderModels(provider: ProviderId): ModelInfo[] {
|
|
|
265
264
|
catalogProvider ?? provider,
|
|
266
265
|
)?.models;
|
|
267
266
|
const models = mergeModelLists(catalogModels, cachedModels);
|
|
268
|
-
return catalogProvider === '
|
|
267
|
+
return catalogProvider === 'kimi'
|
|
269
268
|
? filterAvailableKimiModels(models)
|
|
270
269
|
: models;
|
|
271
270
|
}
|
package/src/types/src/config.ts
CHANGED
|
@@ -13,7 +13,7 @@ export type BuiltInProviderId =
|
|
|
13
13
|
| 'xai'
|
|
14
14
|
| 'zai'
|
|
15
15
|
| 'zai-coding'
|
|
16
|
-
| '
|
|
16
|
+
| 'kimi'
|
|
17
17
|
| 'minimax';
|
|
18
18
|
|
|
19
19
|
/**
|
|
@@ -40,7 +40,7 @@ export type ProviderPromptFamily =
|
|
|
40
40
|
| 'anthropic'
|
|
41
41
|
| 'openai'
|
|
42
42
|
| 'google'
|
|
43
|
-
| '
|
|
43
|
+
| 'kimi'
|
|
44
44
|
| 'minimax'
|
|
45
45
|
| 'glm'
|
|
46
46
|
| 'openai-compatible';
|
|
@@ -52,7 +52,7 @@ export type ProviderFamily =
|
|
|
52
52
|
| 'openai'
|
|
53
53
|
| 'anthropic'
|
|
54
54
|
| 'google'
|
|
55
|
-
| '
|
|
55
|
+
| 'kimi'
|
|
56
56
|
| 'minimax'
|
|
57
57
|
| 'openai-compatible';
|
|
58
58
|
|
|
@@ -66,7 +66,7 @@ export type ModelOwner =
|
|
|
66
66
|
| 'google'
|
|
67
67
|
| 'openrouter'
|
|
68
68
|
| 'xai'
|
|
69
|
-
| '
|
|
69
|
+
| 'kimi'
|
|
70
70
|
| 'qwen'
|
|
71
71
|
| 'zai'
|
|
72
72
|
| 'minimax';
|