@arnilo/prism-provider-kimi 0.0.6 → 0.0.8
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/CHANGELOG.md +19 -0
- package/dist/models.d.ts +2 -2
- package/dist/models.js +42 -6
- package/dist/moonshot.js +17 -4
- package/dist/provider.js +20 -3
- package/dist/thinking.d.ts +6 -3
- package/dist/thinking.js +7 -4
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.0.8] - 2026-07-20
|
|
4
|
+
|
|
5
|
+
- Released with the exact 0.0.8 first-party package graph.
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Featured Moonshot catalog adds `kimi-k2.7-code-highspeed`, `kimi-k2.6`, and `kimi-k2.5` with official thinking defaults (K2.5 intentionally without Preserved Thinking).
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- Featured Coding `k3` defaults `reasoning_effort: "high"` per official Kimi Code docs (Open Platform `kimi-k3` keeps `"max"`); 256K-class featured context windows corrected to the exact official `262_144`.
|
|
14
|
+
- `stripKimiThinkingCompat()` also strips `route` and `preserve_thinking`, so provider-owned routing/serialization keys no longer leak into Anthropic or Chat Completions request bodies.
|
|
15
|
+
- Coding route sends provider-owned `x-api-key` and `anthropic-version: 2023-06-01` headers alongside Bearer per the official third-party setup; caller headers cannot override them.
|
|
16
|
+
- Both stream parsers require protocol completion evidence (`message_stop` on the Coding route, `[DONE]` + terminal `finish_reason` on the Moonshot route) and complete tool-call accumulators; truncated streams end with a terminal `error` instead of a false `done`.
|
|
17
|
+
|
|
18
|
+
## [0.0.7] - 2026-07-19
|
|
19
|
+
|
|
20
|
+
- Released with the exact 0.0.7 first-party package graph.
|
|
21
|
+
|
|
3
22
|
All notable changes to @arnilo/prism-provider-kimi will be documented in this file.
|
|
4
23
|
|
|
5
24
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
package/dist/models.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ export interface KimiModelConfig extends Omit<ModelConfig, "provider" | "compat"
|
|
|
6
6
|
readonly preserveThinking?: boolean;
|
|
7
7
|
/** Official K2.x `thinking` object (`type`, optional `keep`). */
|
|
8
8
|
readonly thinking?: boolean | JsonObject;
|
|
9
|
-
/** Official K3 `reasoning_effort` (`"max"
|
|
9
|
+
/** Official K3 `reasoning_effort` (`"low"`/`"high"`/`"max"`; Open Platform default `"max"`, Coding default `"high"`). */
|
|
10
10
|
readonly reasoning_effort?: string;
|
|
11
11
|
};
|
|
12
12
|
}
|
|
@@ -62,4 +62,4 @@ export declare const kimiCodingModels: readonly [ModelConfig, ModelConfig, Model
|
|
|
62
62
|
* ids from https://platform.kimi.ai/docs/models. Callable via `createMoonshotProvider`
|
|
63
63
|
* when `includeMoonshotModels: true`. Refresh via `listKimiModels()`.
|
|
64
64
|
*/
|
|
65
|
-
export declare const moonshotKimiModels: readonly [ModelConfig, ModelConfig];
|
|
65
|
+
export declare const moonshotKimiModels: readonly [ModelConfig, ModelConfig, ModelConfig, ModelConfig, ModelConfig];
|
package/dist/models.js
CHANGED
|
@@ -89,7 +89,7 @@ export const kimiCodingModels = [
|
|
|
89
89
|
model: "kimi-for-coding",
|
|
90
90
|
displayName: "Kimi For Coding (K2.7 Code)",
|
|
91
91
|
capabilities: { input: ["text", "document", "file"] },
|
|
92
|
-
limits: { contextWindow:
|
|
92
|
+
limits: { contextWindow: 262_144, maxOutputTokens: 64_000 },
|
|
93
93
|
compat: {
|
|
94
94
|
route: "anthropic",
|
|
95
95
|
// Official: thinking always on — omit `thinking` on the wire unless the host sets it.
|
|
@@ -101,7 +101,7 @@ export const kimiCodingModels = [
|
|
|
101
101
|
model: "kimi-for-coding-highspeed",
|
|
102
102
|
displayName: "Kimi For Coding Highspeed",
|
|
103
103
|
capabilities: { input: ["text", "document", "file"] },
|
|
104
|
-
limits: { contextWindow:
|
|
104
|
+
limits: { contextWindow: 262_144, maxOutputTokens: 64_000 },
|
|
105
105
|
compat: {
|
|
106
106
|
route: "anthropic",
|
|
107
107
|
preserveThinking: true,
|
|
@@ -116,8 +116,8 @@ export const kimiCodingModels = [
|
|
|
116
116
|
compat: {
|
|
117
117
|
route: "anthropic",
|
|
118
118
|
preserveThinking: true,
|
|
119
|
-
//
|
|
120
|
-
reasoning_effort: "
|
|
119
|
+
// Official Kimi Code docs: low / high / max; unset effort maps to "high".
|
|
120
|
+
reasoning_effort: "high",
|
|
121
121
|
},
|
|
122
122
|
}),
|
|
123
123
|
];
|
|
@@ -132,13 +132,49 @@ export const moonshotKimiModels = [
|
|
|
132
132
|
model: "kimi-k2.7-code",
|
|
133
133
|
displayName: "Kimi K2.7 Code",
|
|
134
134
|
capabilities: { input: ["text"] },
|
|
135
|
-
limits: { contextWindow:
|
|
135
|
+
limits: { contextWindow: 262_144, maxOutputTokens: 64_000 },
|
|
136
136
|
compat: {
|
|
137
137
|
route: "openai",
|
|
138
138
|
// Official: omit `thinking` for K2.7-code; Preserved Thinking still required on replay.
|
|
139
139
|
preserveThinking: true,
|
|
140
140
|
},
|
|
141
141
|
}),
|
|
142
|
+
defineKimiModel({
|
|
143
|
+
provider: "moonshot",
|
|
144
|
+
model: "kimi-k2.7-code-highspeed",
|
|
145
|
+
displayName: "Kimi K2.7 Code Highspeed",
|
|
146
|
+
capabilities: { input: ["text"] },
|
|
147
|
+
limits: { contextWindow: 262_144, maxOutputTokens: 64_000 },
|
|
148
|
+
compat: {
|
|
149
|
+
route: "openai",
|
|
150
|
+
// Official: same model as kimi-k2.7-code with identical constraints; only output speed differs.
|
|
151
|
+
preserveThinking: true,
|
|
152
|
+
},
|
|
153
|
+
}),
|
|
154
|
+
defineKimiModel({
|
|
155
|
+
provider: "moonshot",
|
|
156
|
+
model: "kimi-k2.6",
|
|
157
|
+
displayName: "Kimi K2.6",
|
|
158
|
+
capabilities: { input: ["text"] },
|
|
159
|
+
limits: { contextWindow: 262_144, maxOutputTokens: 64_000 },
|
|
160
|
+
compat: {
|
|
161
|
+
route: "openai",
|
|
162
|
+
// Official: thinking `{"type":"enabled"}` default; `keep: "all"` opt-in.
|
|
163
|
+
thinking: { type: "enabled" },
|
|
164
|
+
},
|
|
165
|
+
}),
|
|
166
|
+
defineKimiModel({
|
|
167
|
+
provider: "moonshot",
|
|
168
|
+
model: "kimi-k2.5",
|
|
169
|
+
displayName: "Kimi K2.5",
|
|
170
|
+
capabilities: { input: ["text"] },
|
|
171
|
+
limits: { contextWindow: 262_144, maxOutputTokens: 64_000 },
|
|
172
|
+
compat: {
|
|
173
|
+
route: "openai",
|
|
174
|
+
// Official: thinking `{"type":"enabled"}` default; no Preserved Thinking support.
|
|
175
|
+
thinking: { type: "enabled" },
|
|
176
|
+
},
|
|
177
|
+
}),
|
|
142
178
|
defineKimiModel({
|
|
143
179
|
provider: "moonshot",
|
|
144
180
|
model: "kimi-k3",
|
|
@@ -148,7 +184,7 @@ export const moonshotKimiModels = [
|
|
|
148
184
|
compat: {
|
|
149
185
|
route: "openai",
|
|
150
186
|
preserveThinking: true,
|
|
151
|
-
// Open Platform
|
|
187
|
+
// Official Open Platform: low / high / max (default max).
|
|
152
188
|
reasoning_effort: "max",
|
|
153
189
|
},
|
|
154
190
|
}),
|
package/dist/moonshot.js
CHANGED
|
@@ -68,9 +68,13 @@ export function moonshotBody(request) {
|
|
|
68
68
|
export async function* moonshotEvents(body, signal) {
|
|
69
69
|
const tools = new Map();
|
|
70
70
|
let usage;
|
|
71
|
+
let sawDoneMarker = false;
|
|
72
|
+
let sawFinishReason = false;
|
|
71
73
|
for await (const data of readSseData(body, { signal })) {
|
|
72
|
-
if (data === "[DONE]")
|
|
74
|
+
if (data === "[DONE]") {
|
|
75
|
+
sawDoneMarker = true;
|
|
73
76
|
break;
|
|
77
|
+
}
|
|
74
78
|
const chunk = JSON.parse(data);
|
|
75
79
|
usage = mapOpenAIChatUsage(chunk.usage) ?? usage;
|
|
76
80
|
if (chunk.usage) {
|
|
@@ -79,6 +83,8 @@ export async function* moonshotEvents(body, signal) {
|
|
|
79
83
|
yield providerUsage(mapped);
|
|
80
84
|
}
|
|
81
85
|
for (const choice of chunk.choices ?? []) {
|
|
86
|
+
if (choice.finish_reason)
|
|
87
|
+
sawFinishReason = true;
|
|
82
88
|
const delta = choice.delta ?? {};
|
|
83
89
|
if (delta.content)
|
|
84
90
|
yield providerTextDelta(delta.content);
|
|
@@ -100,10 +106,17 @@ export async function* moonshotEvents(body, signal) {
|
|
|
100
106
|
}
|
|
101
107
|
}
|
|
102
108
|
}
|
|
109
|
+
const danglingToolCall = [...tools.values()].some((call) => !call.id || !call.name);
|
|
110
|
+
if (!sawDoneMarker || !sawFinishReason || danglingToolCall) {
|
|
111
|
+
// Truncated streams must fail loudly — emitting done would mark partial output as succeeded.
|
|
112
|
+
yield providerError(new Error(`Moonshot chat stream ended without completion evidence `
|
|
113
|
+
+ `([DONE]: ${sawDoneMarker ? "received" : "missing"}, `
|
|
114
|
+
+ `finish_reason: ${sawFinishReason ? "received" : "missing"}, `
|
|
115
|
+
+ `tool calls complete: ${danglingToolCall ? "no" : "yes"})`));
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
103
118
|
for (const call of tools.values()) {
|
|
104
|
-
|
|
105
|
-
yield providerToolCall(toolCallContent(call.id, call.name, parseJsonObjectArguments(call.argumentsText, { toolName: call.name })));
|
|
106
|
-
}
|
|
119
|
+
yield providerToolCall(toolCallContent(call.id, call.name, parseJsonObjectArguments(call.argumentsText, { toolName: call.name })));
|
|
107
120
|
}
|
|
108
121
|
yield providerDone(usage);
|
|
109
122
|
}
|
package/dist/provider.js
CHANGED
|
@@ -24,6 +24,9 @@ export function createKimiCodingProvider(options = {}) {
|
|
|
24
24
|
"content-type": "application/json",
|
|
25
25
|
"user-agent": options.userAgent ?? "KimiCLI/1.5",
|
|
26
26
|
...(token ? { authorization: `Bearer ${token}` } : {}),
|
|
27
|
+
// Provider-owned Anthropic-route auth: official third-party setup uses
|
|
28
|
+
// ANTHROPIC_API_KEY semantics (x-api-key + anthropic-version).
|
|
29
|
+
...(token ? { "x-api-key": token, "anthropic-version": "2023-06-01" } : {}),
|
|
27
30
|
},
|
|
28
31
|
body: JSON.stringify(body),
|
|
29
32
|
signal: request.signal,
|
|
@@ -66,12 +69,20 @@ export async function kimiAnthropicBody(request) {
|
|
|
66
69
|
export async function* kimiAnthropicEvents(body, signal) {
|
|
67
70
|
const blocks = new Map();
|
|
68
71
|
let usage;
|
|
72
|
+
let sawMessageStop = false;
|
|
69
73
|
for await (const data of readSseData(body, { signal })) {
|
|
70
74
|
if (data === "[DONE]")
|
|
71
75
|
break;
|
|
72
76
|
const event = JSON.parse(data);
|
|
77
|
+
if (event.type === "message_stop")
|
|
78
|
+
sawMessageStop = true;
|
|
73
79
|
if (event.type === "content_block_start" && event.content_block?.type === "tool_use")
|
|
74
80
|
blocks.set(event.index ?? 0, { id: event.content_block.id, name: event.content_block.name, argumentsText: "" });
|
|
81
|
+
if (event.type === "content_block_stop") {
|
|
82
|
+
const current = blocks.get(event.index ?? 0);
|
|
83
|
+
if (current)
|
|
84
|
+
current.complete = true;
|
|
85
|
+
}
|
|
75
86
|
if (event.type === "content_block_delta") {
|
|
76
87
|
const delta = event.delta;
|
|
77
88
|
if (delta?.type === "text_delta" && delta.text)
|
|
@@ -90,10 +101,16 @@ export async function* kimiAnthropicEvents(body, signal) {
|
|
|
90
101
|
if (event.type === "message_delta" && usage)
|
|
91
102
|
yield providerUsage(usage);
|
|
92
103
|
}
|
|
104
|
+
const danglingBlock = [...blocks.values()].some((call) => !call.id || !call.name || !call.complete);
|
|
105
|
+
if (!sawMessageStop || danglingBlock) {
|
|
106
|
+
// Truncated streams must fail loudly — emitting done would mark partial output as succeeded.
|
|
107
|
+
yield providerError(new Error(`Kimi messages stream ended without completion evidence `
|
|
108
|
+
+ `(message_stop: ${sawMessageStop ? "received" : "missing"}, `
|
|
109
|
+
+ `content blocks complete: ${danglingBlock ? "no" : "yes"})`));
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
93
112
|
for (const call of blocks.values()) {
|
|
94
|
-
|
|
95
|
-
yield providerToolCall(toolCallContent(call.id, call.name, parseJsonObjectArguments(call.argumentsText, { toolName: call.name })));
|
|
96
|
-
}
|
|
113
|
+
yield providerToolCall(toolCallContent(call.id, call.name, parseJsonObjectArguments(call.argumentsText, { toolName: call.name })));
|
|
97
114
|
}
|
|
98
115
|
yield providerDone(usage);
|
|
99
116
|
}
|
package/dist/thinking.d.ts
CHANGED
|
@@ -6,8 +6,8 @@ import type { JsonObject, ProviderRequest } from "@arnilo/prism";
|
|
|
6
6
|
*/
|
|
7
7
|
export declare function kimiThinking(request: ProviderRequest): JsonObject | undefined;
|
|
8
8
|
/**
|
|
9
|
-
* Official K3 top-level `reasoning_effort`
|
|
10
|
-
*
|
|
9
|
+
* Official K3 top-level `reasoning_effort`: `"low"` / `"high"` / `"max"`.
|
|
10
|
+
* Open Platform default is `"max"`; Kimi Code default is `"high"`.
|
|
11
11
|
* Request wins over model default.
|
|
12
12
|
* @see https://platform.kimi.ai/docs/guide/use-thinking-effort
|
|
13
13
|
*/
|
|
@@ -18,5 +18,8 @@ export declare function kimiReasoningEffort(request: ProviderRequest): string |
|
|
|
18
18
|
* Request `compat.preserveThinking` wins over model default.
|
|
19
19
|
*/
|
|
20
20
|
export declare function kimiPreserveThinking(request: ProviderRequest): boolean;
|
|
21
|
-
/**
|
|
21
|
+
/**
|
|
22
|
+
* Strip provider-owned compat keys so the opaque compat spread cannot leak
|
|
23
|
+
* routing/serialization directives (or inverted thinking values) into wire bodies.
|
|
24
|
+
*/
|
|
22
25
|
export declare function stripKimiThinkingCompat(compat: JsonObject | undefined): JsonObject;
|
package/dist/thinking.js
CHANGED
|
@@ -12,8 +12,8 @@ export function kimiThinking(request) {
|
|
|
12
12
|
return value === true ? { type: "enabled" } : undefined;
|
|
13
13
|
}
|
|
14
14
|
/**
|
|
15
|
-
* Official K3 top-level `reasoning_effort`
|
|
16
|
-
*
|
|
15
|
+
* Official K3 top-level `reasoning_effort`: `"low"` / `"high"` / `"max"`.
|
|
16
|
+
* Open Platform default is `"max"`; Kimi Code default is `"high"`.
|
|
17
17
|
* Request wins over model default.
|
|
18
18
|
* @see https://platform.kimi.ai/docs/guide/use-thinking-effort
|
|
19
19
|
*/
|
|
@@ -32,11 +32,14 @@ export function kimiPreserveThinking(request) {
|
|
|
32
32
|
const value = request.options?.compat?.preserveThinking ?? request.model.compat?.preserveThinking;
|
|
33
33
|
return value === true;
|
|
34
34
|
}
|
|
35
|
-
/**
|
|
35
|
+
/**
|
|
36
|
+
* Strip provider-owned compat keys so the opaque compat spread cannot leak
|
|
37
|
+
* routing/serialization directives (or inverted thinking values) into wire bodies.
|
|
38
|
+
*/
|
|
36
39
|
export function stripKimiThinkingCompat(compat) {
|
|
37
40
|
if (!compat)
|
|
38
41
|
return {};
|
|
39
|
-
const { thinking: _thinking, reasoning_effort: _effort, reasoningEffort: _effortCamel, preserveThinking: _preserve, ...rest } = compat;
|
|
42
|
+
const { thinking: _thinking, reasoning_effort: _effort, reasoningEffort: _effortCamel, preserveThinking: _preserve, preserve_thinking: _preserveSnake, route: _route, ...rest } = compat;
|
|
40
43
|
return rest;
|
|
41
44
|
}
|
|
42
45
|
//# sourceMappingURL=thinking.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arnilo/prism-provider-kimi",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.8",
|
|
4
4
|
"description": "Kimi provider package for Prism.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"pack:dry-run": "npm pack --dry-run"
|
|
26
26
|
},
|
|
27
27
|
"peerDependencies": {
|
|
28
|
-
"@arnilo/prism": "0.0.
|
|
28
|
+
"@arnilo/prism": "0.0.8"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
31
|
"@arnilo/prism": "file:../.."
|