@eddyskywalker/dsh-chatgpt-subscription 0.37.0 → 0.38.1
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 +24 -0
- package/README.md +11 -8
- package/lib/client.js +263 -87
- package/lib/client.js.map +1 -1
- package/lib/index.js +426 -130
- package/lib/types/client/kimi-code/KimiCodeSection.d.ts.map +1 -1
- package/lib/types/client/kimi-code/KimiModelCapabilities.d.ts.map +1 -1
- package/lib/types/client/kimi-code/labels.d.ts +66 -0
- package/lib/types/client/kimi-code/labels.d.ts.map +1 -0
- package/lib/types/client/kimi-code/locales.d.ts +52 -11
- package/lib/types/client/kimi-code/locales.d.ts.map +1 -1
- package/lib/types/client/locales-ru/kimi-code.d.ts.map +1 -1
- package/lib/types/host/kimi-code/adapter.d.ts.map +1 -1
- package/lib/types/host/kimi-code/client.d.ts.map +1 -1
- package/lib/types/host/kimi-code/mapper.d.ts +117 -20
- package/lib/types/host/kimi-code/mapper.d.ts.map +1 -1
- package/lib/types/host/kimi-code/model-catalog.d.ts +52 -4
- package/lib/types/host/kimi-code/model-catalog.d.ts.map +1 -1
- package/lib/types/host/kimi-code/routes.d.ts.map +1 -1
- package/lib/types/host/kimi-code/types.d.ts +88 -7
- package/lib/types/host/kimi-code/types.d.ts.map +1 -1
- package/lib/types/shared/kimi-code-contracts.d.ts +30 -6
- package/lib/types/shared/kimi-code-contracts.d.ts.map +1 -1
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -23621,114 +23621,6 @@ var OllamaAccountPool = class extends AccountPoolCore {
|
|
|
23621
23621
|
}
|
|
23622
23622
|
};
|
|
23623
23623
|
//#endregion
|
|
23624
|
-
//#region src/host/kimi-code/model-catalog.ts
|
|
23625
|
-
/**
|
|
23626
|
-
* The four ids the subscription serves today.
|
|
23627
|
-
*
|
|
23628
|
-
* `kimi-for-coding` is the alias that never changes: Moonshot upgrades the model
|
|
23629
|
-
* behind it in place (K2.7 Code became K2.8 Preview without a config change), so
|
|
23630
|
-
* this entry is the durable default a user can leave selected.
|
|
23631
|
-
*/
|
|
23632
|
-
const KIMI_CODE_MODELS = [
|
|
23633
|
-
{
|
|
23634
|
-
id: "k3",
|
|
23635
|
-
name: "K3",
|
|
23636
|
-
version: "K3",
|
|
23637
|
-
contextWindow: 262144,
|
|
23638
|
-
maxContextWindow: 1048576,
|
|
23639
|
-
maxTokens: 32768,
|
|
23640
|
-
inputModalities: [
|
|
23641
|
-
"text",
|
|
23642
|
-
"image",
|
|
23643
|
-
"video"
|
|
23644
|
-
],
|
|
23645
|
-
reasoningEfforts: [
|
|
23646
|
-
"low",
|
|
23647
|
-
"high",
|
|
23648
|
-
"max"
|
|
23649
|
-
],
|
|
23650
|
-
defaultReasoningEffort: "high",
|
|
23651
|
-
minimumPlan: "Moderato",
|
|
23652
|
-
contextPlan: "Allegretto",
|
|
23653
|
-
description: "The most capable flagship coding model: 2.8T parameters, 1M context window. The 1M context consumes about twice the quota of k3-256k.",
|
|
23654
|
-
supportsDynamicTools: true,
|
|
23655
|
-
quotaMultiplier: 2,
|
|
23656
|
-
speed: "regular"
|
|
23657
|
-
},
|
|
23658
|
-
{
|
|
23659
|
-
id: "k3-256k",
|
|
23660
|
-
name: "K3 (256K)",
|
|
23661
|
-
version: "K3",
|
|
23662
|
-
contextWindow: 262144,
|
|
23663
|
-
maxContextWindow: null,
|
|
23664
|
-
maxTokens: 32768,
|
|
23665
|
-
inputModalities: ["text", "image"],
|
|
23666
|
-
reasoningEfforts: [
|
|
23667
|
-
"low",
|
|
23668
|
-
"high",
|
|
23669
|
-
"max"
|
|
23670
|
-
],
|
|
23671
|
-
defaultReasoningEffort: "high",
|
|
23672
|
-
minimumPlan: "Moderato",
|
|
23673
|
-
contextPlan: null,
|
|
23674
|
-
description: "The 256K context version of K3, available to every Moderato member and above. Costs about half the quota of k3 with 1M context, and does not accept video input.",
|
|
23675
|
-
supportsDynamicTools: true,
|
|
23676
|
-
quotaMultiplier: 1,
|
|
23677
|
-
speed: "regular"
|
|
23678
|
-
},
|
|
23679
|
-
{
|
|
23680
|
-
id: "kimi-for-coding",
|
|
23681
|
-
name: "Kimi for Coding",
|
|
23682
|
-
version: "K2.8 Preview",
|
|
23683
|
-
contextWindow: 1048576,
|
|
23684
|
-
maxContextWindow: null,
|
|
23685
|
-
maxTokens: 32768,
|
|
23686
|
-
inputModalities: [
|
|
23687
|
-
"text",
|
|
23688
|
-
"image",
|
|
23689
|
-
"video"
|
|
23690
|
-
],
|
|
23691
|
-
reasoningEfforts: [
|
|
23692
|
-
"low",
|
|
23693
|
-
"high",
|
|
23694
|
-
"max"
|
|
23695
|
-
],
|
|
23696
|
-
defaultReasoningEffort: "max",
|
|
23697
|
-
minimumPlan: null,
|
|
23698
|
-
contextPlan: null,
|
|
23699
|
-
description: "Performance close to K3 with more efficient thinking, and up to 1M context on every plan. Good at code completion and routine development tasks.",
|
|
23700
|
-
supportsDynamicTools: true,
|
|
23701
|
-
quotaMultiplier: 1,
|
|
23702
|
-
speed: "regular"
|
|
23703
|
-
},
|
|
23704
|
-
{
|
|
23705
|
-
id: "kimi-for-coding-highspeed",
|
|
23706
|
-
name: "Kimi for Coding HighSpeed",
|
|
23707
|
-
version: "K2.7 Code HighSpeed",
|
|
23708
|
-
contextWindow: 262144,
|
|
23709
|
-
maxContextWindow: null,
|
|
23710
|
-
maxTokens: 32768,
|
|
23711
|
-
inputModalities: [
|
|
23712
|
-
"text",
|
|
23713
|
-
"image",
|
|
23714
|
-
"video"
|
|
23715
|
-
],
|
|
23716
|
-
reasoningEfforts: ["high"],
|
|
23717
|
-
defaultReasoningEffort: "high",
|
|
23718
|
-
minimumPlan: "Allegretto",
|
|
23719
|
-
contextPlan: null,
|
|
23720
|
-
description: "The high-speed version of K2.7 Code with the same coding ability and roughly 5-6x faster output, at 3x quota usage. Requires the Allegretto plan or above.",
|
|
23721
|
-
supportsDynamicTools: false,
|
|
23722
|
-
quotaMultiplier: 3,
|
|
23723
|
-
speed: "highspeed"
|
|
23724
|
-
}
|
|
23725
|
-
];
|
|
23726
|
-
const BY_ID$1 = new Map(KIMI_CODE_MODELS.map((model) => [model.id, model]));
|
|
23727
|
-
/** Registry entry for one model id, or undefined when the id is unknown. */
|
|
23728
|
-
function kimiCodeModelDef(modelId) {
|
|
23729
|
-
return BY_ID$1.get(modelId.trim());
|
|
23730
|
-
}
|
|
23731
|
-
//#endregion
|
|
23732
23624
|
//#region src/host/common/request-images.ts
|
|
23733
23625
|
function isRecord$39(value) {
|
|
23734
23626
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -24122,6 +24014,194 @@ function imageBlockToInline$2(block, images) {
|
|
|
24122
24014
|
} : void 0;
|
|
24123
24015
|
}
|
|
24124
24016
|
//#endregion
|
|
24017
|
+
//#region src/host/kimi-code/model-catalog.ts
|
|
24018
|
+
/**
|
|
24019
|
+
* Request-body ceiling the 1M-context tier defaults to.
|
|
24020
|
+
*
|
|
24021
|
+
* The 2 MB figure this line used to apply to every model comes from the gateway's
|
|
24022
|
+
* generic error example and was never measured against a 1M window, while a real
|
|
24023
|
+
* 1M session (3-4 MB of Chinese prose) hits it long before the window is full.
|
|
24024
|
+
* The official kimi-cli ships no byte guard at all, so the ceiling is this
|
|
24025
|
+
* plugin's own safety net rather than a client requirement.
|
|
24026
|
+
*
|
|
24027
|
+
* 8 MiB is sized so bytes never become the binding limit for a 1M session: that
|
|
24028
|
+
* window's body is roughly 4 MB of English or 4.5 MB of dense Chinese, so 8 MiB
|
|
24029
|
+
* leaves nearly double the headroom. What binds first is the model's own token
|
|
24030
|
+
* window — the service answers "Your request exceeded model token limit", which
|
|
24031
|
+
* common/context-overflow.ts already normalizes to CONTEXT_WINDOW_EXCEEDED, so
|
|
24032
|
+
* compaction and retry behave exactly as they did before.
|
|
24033
|
+
*
|
|
24034
|
+
* The number is still an UPPER BOUND pending measurement, not a documented
|
|
24035
|
+
* gateway limit: a deployment that has measured its own gateway pins the real
|
|
24036
|
+
* figure with DSH_KIMI_CODE_MAX_BODY_BYTES. The 256K tier keeps 2 MB, where the
|
|
24037
|
+
* old ceiling and the window line up.
|
|
24038
|
+
*/
|
|
24039
|
+
const LONG_CONTEXT_MESSAGE_BODY_BYTES = 8 * 1024 * 1024;
|
|
24040
|
+
/**
|
|
24041
|
+
* The ids the subscription serves today.
|
|
24042
|
+
*
|
|
24043
|
+
* `kimi-for-coding` is the alias that never changes: Moonshot upgrades the model
|
|
24044
|
+
* behind it in place (K2.7 Code became K2.8 Preview without a config change), so
|
|
24045
|
+
* this entry is the durable default a user can leave selected.
|
|
24046
|
+
*/
|
|
24047
|
+
const KIMI_CODE_MODELS = [
|
|
24048
|
+
{
|
|
24049
|
+
id: "k3",
|
|
24050
|
+
name: "K3",
|
|
24051
|
+
version: "K3",
|
|
24052
|
+
contextWindow: 262144,
|
|
24053
|
+
maxContextWindow: 1048576,
|
|
24054
|
+
maxTokens: 32768,
|
|
24055
|
+
maxRequestBodyBytes: LONG_CONTEXT_MESSAGE_BODY_BYTES,
|
|
24056
|
+
inputModalities: [
|
|
24057
|
+
"text",
|
|
24058
|
+
"image",
|
|
24059
|
+
"video"
|
|
24060
|
+
],
|
|
24061
|
+
reasoningEfforts: [
|
|
24062
|
+
"low",
|
|
24063
|
+
"high",
|
|
24064
|
+
"max"
|
|
24065
|
+
],
|
|
24066
|
+
defaultReasoningEffort: "high",
|
|
24067
|
+
minimumPlan: "Moderato",
|
|
24068
|
+
contextPlan: "Allegretto",
|
|
24069
|
+
description: "The most capable flagship coding model: 2.8T parameters, 1M context window. The 1M context consumes about twice the quota of k3-256k.",
|
|
24070
|
+
supportsDynamicTools: true,
|
|
24071
|
+
quotaMultiplier: 2,
|
|
24072
|
+
speed: "regular"
|
|
24073
|
+
},
|
|
24074
|
+
{
|
|
24075
|
+
id: "k3-256k",
|
|
24076
|
+
name: "K3 (256K)",
|
|
24077
|
+
version: "K3",
|
|
24078
|
+
contextWindow: 262144,
|
|
24079
|
+
maxContextWindow: null,
|
|
24080
|
+
maxTokens: 32768,
|
|
24081
|
+
maxRequestBodyBytes: MAX_MESSAGE_BODY_BYTES,
|
|
24082
|
+
inputModalities: ["text", "image"],
|
|
24083
|
+
reasoningEfforts: [
|
|
24084
|
+
"low",
|
|
24085
|
+
"high",
|
|
24086
|
+
"max"
|
|
24087
|
+
],
|
|
24088
|
+
defaultReasoningEffort: "high",
|
|
24089
|
+
minimumPlan: "Moderato",
|
|
24090
|
+
contextPlan: null,
|
|
24091
|
+
description: "The 256K context version of K3, available to every Moderato member and above. Costs about half the quota of k3 with 1M context, and does not accept video input.",
|
|
24092
|
+
supportsDynamicTools: true,
|
|
24093
|
+
quotaMultiplier: 1,
|
|
24094
|
+
speed: "regular"
|
|
24095
|
+
},
|
|
24096
|
+
{
|
|
24097
|
+
id: "kimi-for-coding",
|
|
24098
|
+
name: "Kimi for Coding",
|
|
24099
|
+
version: "K2.8 Preview",
|
|
24100
|
+
contextWindow: 1048576,
|
|
24101
|
+
maxContextWindow: null,
|
|
24102
|
+
maxTokens: 32768,
|
|
24103
|
+
maxRequestBodyBytes: LONG_CONTEXT_MESSAGE_BODY_BYTES,
|
|
24104
|
+
inputModalities: [
|
|
24105
|
+
"text",
|
|
24106
|
+
"image",
|
|
24107
|
+
"video"
|
|
24108
|
+
],
|
|
24109
|
+
reasoningEfforts: [
|
|
24110
|
+
"low",
|
|
24111
|
+
"high",
|
|
24112
|
+
"max"
|
|
24113
|
+
],
|
|
24114
|
+
defaultReasoningEffort: "max",
|
|
24115
|
+
minimumPlan: null,
|
|
24116
|
+
contextPlan: null,
|
|
24117
|
+
description: "Performance close to K3 with more efficient thinking, and up to 1M context on every plan. Good at code completion and routine development tasks.",
|
|
24118
|
+
supportsDynamicTools: true,
|
|
24119
|
+
quotaMultiplier: 1,
|
|
24120
|
+
speed: "regular"
|
|
24121
|
+
},
|
|
24122
|
+
{
|
|
24123
|
+
id: "kimi-for-coding-highspeed",
|
|
24124
|
+
name: "Kimi for Coding HighSpeed",
|
|
24125
|
+
version: "K2.7 Code HighSpeed",
|
|
24126
|
+
contextWindow: 262144,
|
|
24127
|
+
maxContextWindow: null,
|
|
24128
|
+
maxTokens: 32768,
|
|
24129
|
+
maxRequestBodyBytes: MAX_MESSAGE_BODY_BYTES,
|
|
24130
|
+
inputModalities: [
|
|
24131
|
+
"text",
|
|
24132
|
+
"image",
|
|
24133
|
+
"video"
|
|
24134
|
+
],
|
|
24135
|
+
reasoningEfforts: ["high"],
|
|
24136
|
+
defaultReasoningEffort: "high",
|
|
24137
|
+
minimumPlan: "Allegretto",
|
|
24138
|
+
contextPlan: null,
|
|
24139
|
+
description: "The high-speed version of K2.7 Code with the same coding ability and roughly 5-6x faster output, at 3x quota usage. Requires the Allegretto plan or above.",
|
|
24140
|
+
supportsDynamicTools: false,
|
|
24141
|
+
quotaMultiplier: 3,
|
|
24142
|
+
speed: "highspeed"
|
|
24143
|
+
},
|
|
24144
|
+
{
|
|
24145
|
+
id: "k3.1-pro",
|
|
24146
|
+
name: "K3.1 Pro",
|
|
24147
|
+
version: "K3.1 Pro",
|
|
24148
|
+
contextWindow: 262144,
|
|
24149
|
+
maxContextWindow: 1048576,
|
|
24150
|
+
maxTokens: 32768,
|
|
24151
|
+
maxRequestBodyBytes: LONG_CONTEXT_MESSAGE_BODY_BYTES,
|
|
24152
|
+
inputModalities: [
|
|
24153
|
+
"text",
|
|
24154
|
+
"image",
|
|
24155
|
+
"video"
|
|
24156
|
+
],
|
|
24157
|
+
reasoningEfforts: [
|
|
24158
|
+
"low",
|
|
24159
|
+
"high",
|
|
24160
|
+
"max"
|
|
24161
|
+
],
|
|
24162
|
+
defaultReasoningEffort: "max",
|
|
24163
|
+
thinkingType: "only",
|
|
24164
|
+
minimumPlan: "Moderato",
|
|
24165
|
+
contextPlan: "Allegretto",
|
|
24166
|
+
description: "The K3.1 Pro flagship: 3T parameters, a 256K context window on Plus/Moderato and 1M on Pro/Allegretto and above. Thinking runs at low/high/max, defaults to max, and cannot be disabled.",
|
|
24167
|
+
supportsDynamicTools: true,
|
|
24168
|
+
quotaMultiplier: null,
|
|
24169
|
+
speed: "regular"
|
|
24170
|
+
},
|
|
24171
|
+
{
|
|
24172
|
+
id: "k3.1-pro-highspeed",
|
|
24173
|
+
name: "K3.1 Pro Highspeed",
|
|
24174
|
+
version: "K3.1 Pro Highspeed",
|
|
24175
|
+
contextWindow: 1048576,
|
|
24176
|
+
maxContextWindow: null,
|
|
24177
|
+
maxTokens: 32768,
|
|
24178
|
+
maxRequestBodyBytes: LONG_CONTEXT_MESSAGE_BODY_BYTES,
|
|
24179
|
+
inputModalities: [
|
|
24180
|
+
"text",
|
|
24181
|
+
"image",
|
|
24182
|
+
"video"
|
|
24183
|
+
],
|
|
24184
|
+
reasoningEfforts: [
|
|
24185
|
+
"low",
|
|
24186
|
+
"high",
|
|
24187
|
+
"max"
|
|
24188
|
+
],
|
|
24189
|
+
defaultReasoningEffort: "max",
|
|
24190
|
+
thinkingType: "only",
|
|
24191
|
+
minimumPlan: "Allegretto",
|
|
24192
|
+
contextPlan: null,
|
|
24193
|
+
description: "The high-speed K3.1 Pro with a 1M context window and faster output, at about twice the quota of the regular version. Requires the Pro/Allegretto plan or above.",
|
|
24194
|
+
supportsDynamicTools: true,
|
|
24195
|
+
quotaMultiplier: null,
|
|
24196
|
+
speed: "highspeed"
|
|
24197
|
+
}
|
|
24198
|
+
];
|
|
24199
|
+
const BY_ID$1 = new Map(KIMI_CODE_MODELS.map((model) => [model.id, model]));
|
|
24200
|
+
/** Registry entry for one model id, or undefined when the id is unknown. */
|
|
24201
|
+
function kimiCodeModelDef(modelId) {
|
|
24202
|
+
return BY_ID$1.get(modelId.trim());
|
|
24203
|
+
}
|
|
24204
|
+
//#endregion
|
|
24125
24205
|
//#region src/host/kimi-code/types.ts
|
|
24126
24206
|
const PROVIDER_ID$8 = "kimi-code";
|
|
24127
24207
|
const PROVIDER_NAME$7 = "Kimi Code";
|
|
@@ -24222,9 +24302,22 @@ function openAIUrl(suffix, region = "mainland-cn") {
|
|
|
24222
24302
|
* spanning both tiers could not express "relax the text ceiling, leave the video
|
|
24223
24303
|
* one alone", and a value chosen for a 2 MB conversation would collapse the video
|
|
24224
24304
|
* tier with it. MiniMax's video budget is likewise a bare constant.
|
|
24305
|
+
*
|
|
24306
|
+
* The text/image tier is now graded by model: this constant is what the 256K
|
|
24307
|
+
* models keep and what an unknown model falls back to, while the 1M models
|
|
24308
|
+
* declare their own, larger ceiling in the registry. {@link maxRequestBodyBytesFor}
|
|
24309
|
+
* is the resolver that applies that grade.
|
|
24225
24310
|
*/
|
|
24226
24311
|
const DEFAULT_MAX_MESSAGE_BODY_BYTES$1 = MAX_MESSAGE_BODY_BYTES;
|
|
24227
|
-
/**
|
|
24312
|
+
/**
|
|
24313
|
+
* Ceiling this process enforces when the caller has no model to key on.
|
|
24314
|
+
*
|
|
24315
|
+
* Kept alongside {@link maxRequestBodyBytesFor} rather than folded into it: this
|
|
24316
|
+
* is the answer for "what does this deployment allow at all", which the video
|
|
24317
|
+
* budget and the settings reporting paths need without naming a model. A request
|
|
24318
|
+
* that DOES name one goes through the per-model resolver below, so a 1M-tier
|
|
24319
|
+
* session gets its own tier instead of this floor.
|
|
24320
|
+
*/
|
|
24228
24321
|
function maxMessageBodyBytes$1(env = process.env) {
|
|
24229
24322
|
const raw = (env.DSH_KIMI_CODE_MAX_BODY_BYTES ?? "").trim();
|
|
24230
24323
|
if (raw === "") return DEFAULT_MAX_MESSAGE_BODY_BYTES$1;
|
|
@@ -24233,6 +24326,35 @@ function maxMessageBodyBytes$1(env = process.env) {
|
|
|
24233
24326
|
return Math.floor(parsed);
|
|
24234
24327
|
}
|
|
24235
24328
|
/**
|
|
24329
|
+
* Request-body ceiling for one model, in precedence order.
|
|
24330
|
+
*
|
|
24331
|
+
* The middleware gateway that rejects a body is shared and the sessions are not:
|
|
24332
|
+
* a 1M-tier session produces several megabytes of conversation the 256K tier
|
|
24333
|
+
* cannot, so one number for both either starves the long tier or leaves the
|
|
24334
|
+
* short one unguarded. Hence three sources, highest priority first:
|
|
24335
|
+
*
|
|
24336
|
+
* 1. DSH_KIMI_CODE_MAX_BODY_BYTES — a measured figure for THIS deployment, so it
|
|
24337
|
+
* wins over every per-model default. It still has to be a positive integer:
|
|
24338
|
+
* a typo falls through to the model's own default rather than switching the
|
|
24339
|
+
* guard off, which is the one failure this variable must never cause;
|
|
24340
|
+
* 2. the model's {@link KimiCodeCatalogModel.maxRequestBodyBytes};
|
|
24341
|
+
* 3. {@link DEFAULT_MAX_MESSAGE_BODY_BYTES}, for a model the registry does not
|
|
24342
|
+
* know — an unknown id keeps the most conservative ceiling rather than
|
|
24343
|
+
* inheriting a long-context allowance nothing has vouched for.
|
|
24344
|
+
*
|
|
24345
|
+
* @param model the registry row for the model being called, or undefined when
|
|
24346
|
+
* the id is not one this route ships.
|
|
24347
|
+
* @param env environment the override is read from, injectable for tests.
|
|
24348
|
+
*/
|
|
24349
|
+
function maxRequestBodyBytesFor(model, env = process.env) {
|
|
24350
|
+
const raw = (env.DSH_KIMI_CODE_MAX_BODY_BYTES ?? "").trim();
|
|
24351
|
+
if (raw !== "") {
|
|
24352
|
+
const parsed = Number(raw);
|
|
24353
|
+
if (Number.isFinite(parsed) && parsed > 0) return Math.floor(parsed);
|
|
24354
|
+
}
|
|
24355
|
+
return model?.maxRequestBodyBytes ?? DEFAULT_MAX_MESSAGE_BODY_BYTES$1;
|
|
24356
|
+
}
|
|
24357
|
+
/**
|
|
24236
24358
|
* Bytes one METERED token is assumed to occupy when a deployment asks this route
|
|
24237
24359
|
* to fold its published window against the byte ceiling.
|
|
24238
24360
|
*
|
|
@@ -24357,17 +24479,79 @@ function maxRequestImageBytes$1(env = process.env) {
|
|
|
24357
24479
|
/**
|
|
24358
24480
|
* Which wire dialect a model id is served over.
|
|
24359
24481
|
*
|
|
24360
|
-
*
|
|
24361
|
-
*
|
|
24362
|
-
*
|
|
24363
|
-
*
|
|
24482
|
+
* Always the OpenAI-compatible chat completions dialect: this line uses that one
|
|
24483
|
+
* protocol for every model, K3.1 Pro included, which is what the official agent
|
|
24484
|
+
* configures for the managed provider (`type = "kimi"`). The Anthropic Messages
|
|
24485
|
+
* dialect remains reachable only when a live listing declares it for an id
|
|
24486
|
+
* (see `wireForCatalogEntry`), so the answer here is a constant rather than a
|
|
24487
|
+
* per-model table.
|
|
24364
24488
|
*/
|
|
24365
24489
|
function wireForModel(_modelId) {
|
|
24366
24490
|
return "openai";
|
|
24367
24491
|
}
|
|
24368
|
-
/**
|
|
24492
|
+
/**
|
|
24493
|
+
* Thinking levels one model advertises, from the static registry.
|
|
24494
|
+
*
|
|
24495
|
+
* A registry row that declares `thinkingType: 'only'` cannot be asked to stop
|
|
24496
|
+
* reasoning — the service answers HTTP 400 for a disabled-thinking request — so
|
|
24497
|
+
* `none` is filtered out of the list it publishes.
|
|
24498
|
+
*/
|
|
24369
24499
|
function reasoningEffortsFor(modelId) {
|
|
24370
|
-
|
|
24500
|
+
const declared = kimiCodeModelDef(modelId)?.reasoningEfforts ?? [];
|
|
24501
|
+
if (kimiCodeModelDef(modelId)?.thinkingType === "only") return declared.filter((effort) => effort !== "none");
|
|
24502
|
+
return [...declared];
|
|
24503
|
+
}
|
|
24504
|
+
/**
|
|
24505
|
+
* Thinking level one model uses when the conversation does not pick one.
|
|
24506
|
+
*
|
|
24507
|
+
* A declared default that the resolved effort list no longer contains is
|
|
24508
|
+
* dropped rather than carried through: with `only` in force the list can lose
|
|
24509
|
+
* `none`, and a default naming a level the model can no longer be asked for
|
|
24510
|
+
* would fail on the first turn that relied on it.
|
|
24511
|
+
*/
|
|
24512
|
+
function defaultReasoningEffortFor(modelId) {
|
|
24513
|
+
const declared = kimiCodeModelDef(modelId)?.defaultReasoningEffort ?? void 0;
|
|
24514
|
+
if (declared === null || declared === void 0) return void 0;
|
|
24515
|
+
return reasoningEffortsFor(modelId).includes(declared) ? declared : void 0;
|
|
24516
|
+
}
|
|
24517
|
+
/**
|
|
24518
|
+
* How a model handles thinking, from the static registry.
|
|
24519
|
+
*
|
|
24520
|
+
* Exposed so the request builder and the settings card read the same row rather
|
|
24521
|
+
* than each re-deriving the rule; `undefined` means the registry says nothing
|
|
24522
|
+
* about this id, which is not the same as "thinking can be switched off".
|
|
24523
|
+
*/
|
|
24524
|
+
function thinkingTypeFor(modelId) {
|
|
24525
|
+
return kimiCodeModelDef(modelId)?.thinkingType;
|
|
24526
|
+
}
|
|
24527
|
+
/**
|
|
24528
|
+
* Raise a disabled-thinking request to a level the model can actually run.
|
|
24529
|
+
*
|
|
24530
|
+
* Asking a thinking-only model for `none` is refused by the service with
|
|
24531
|
+
* HTTP 400 ("K3.1 Pro does not support disabled thinking mode"), and the user's
|
|
24532
|
+
* real intent there is "don't spend my quota on thinking", not "fail the turn".
|
|
24533
|
+
* So the effort is lifted to the model's own default — `max` for the K3.1 pair —
|
|
24534
|
+
* and the lift is REPORTED through `coercedFrom` so a caller can tell the user
|
|
24535
|
+
* what happened instead of silently spending more than they asked for.
|
|
24536
|
+
*
|
|
24537
|
+
* A model that does not declare `only`, and any effort other than `none`, is
|
|
24538
|
+
* returned untouched. When a thinking-only row declares no default the effort
|
|
24539
|
+
* becomes `undefined`, which sends no level at all and leaves the service on its
|
|
24540
|
+
* own default — still never a disabled-thinking request.
|
|
24541
|
+
*/
|
|
24542
|
+
function coerceThinkingEffort(modelId, effort) {
|
|
24543
|
+
if (effort !== "none") return {
|
|
24544
|
+
effort,
|
|
24545
|
+
coercedFrom: null
|
|
24546
|
+
};
|
|
24547
|
+
if (thinkingTypeFor(modelId) !== "only") return {
|
|
24548
|
+
effort,
|
|
24549
|
+
coercedFrom: null
|
|
24550
|
+
};
|
|
24551
|
+
return {
|
|
24552
|
+
effort: defaultReasoningEffortFor(modelId),
|
|
24553
|
+
coercedFrom: "none"
|
|
24554
|
+
};
|
|
24371
24555
|
}
|
|
24372
24556
|
/**
|
|
24373
24557
|
* Accepted request modalities for one model.
|
|
@@ -25757,7 +25941,7 @@ function wireForCatalogEntry(modelId, catalog) {
|
|
|
25757
25941
|
function reasoningEffortsForEntry(modelId, catalog) {
|
|
25758
25942
|
const entry = catalog.find((model) => model.id === modelId);
|
|
25759
25943
|
const declared = entry?.reasoningEfforts ?? reasoningEffortsFor(modelId);
|
|
25760
|
-
switch (entry?.thinkingType) {
|
|
25944
|
+
switch (entry?.thinkingType ?? thinkingTypeFor(modelId)) {
|
|
25761
25945
|
case "no": return [];
|
|
25762
25946
|
case "only": return declared.filter((effort) => effort !== "none");
|
|
25763
25947
|
default: return [...declared];
|
|
@@ -25830,6 +26014,7 @@ function buildModelOptions(catalog, enabledModelIds, contextWindowOverrides) {
|
|
|
25830
26014
|
const contextWindow = typeof override === "number" && Number.isFinite(override) && override > 0 ? override : model.contextWindow ?? 262144;
|
|
25831
26015
|
const efforts = reasoningEffortsForEntry(model.id, catalog);
|
|
25832
26016
|
const defaultEffort = defaultReasoningEffortForEntry(model.id, catalog);
|
|
26017
|
+
const thinkingType = model.thinkingType ?? thinkingTypeFor(model.id);
|
|
25833
26018
|
const declaredInputCap = maxInputTokensForEntry(model.id, catalog);
|
|
25834
26019
|
const promptBudget = declaredInputCap === void 0 ? contextWindow : Math.min(contextWindow, declaredInputCap);
|
|
25835
26020
|
return {
|
|
@@ -25843,6 +26028,7 @@ function buildModelOptions(catalog, enabledModelIds, contextWindowOverrides) {
|
|
|
25843
26028
|
defaultMaxTokens: maxOutputTokensFor$4(model.id, contextWindow),
|
|
25844
26029
|
...efforts.length === 0 ? {} : { reasoningEfforts: [...efforts] },
|
|
25845
26030
|
...defaultEffort === void 0 ? {} : { defaultReasoningEffort: defaultEffort },
|
|
26031
|
+
...thinkingType === void 0 ? {} : { thinkingType },
|
|
25846
26032
|
wire: model.protocol ?? wireForModel(model.id),
|
|
25847
26033
|
description: model.description ?? kimiCodeModelDef(model.id)?.description ?? null,
|
|
25848
26034
|
supportsVideo: model.supportsVideo ?? kimiCodeModelDef(model.id)?.inputModalities.includes("video") ?? false,
|
|
@@ -27673,12 +27859,40 @@ function buildRequest(options, wire, images = NO_RESOLVED_IMAGES$3, preserveThin
|
|
|
27673
27859
|
recordDriftCause(trackPrefixStability(options), options.sessionId);
|
|
27674
27860
|
return wire === "anthropic" ? buildAnthropicRequest(options, images, media) : buildOpenAIRequest(options, images, preserveThinking, media);
|
|
27675
27861
|
}
|
|
27676
|
-
|
|
27862
|
+
/**
|
|
27863
|
+
* Reject a request the service would refuse for its size.
|
|
27864
|
+
*
|
|
27865
|
+
* This is the most frequently reported 400 on the coding endpoint, and it is
|
|
27866
|
+
* worth catching locally for two reasons: the message can name the actual
|
|
27867
|
+
* remedy (DSH's compaction), and a request that cannot succeed should not be
|
|
27868
|
+
* sent at all. The measured size is the real serialized body, so it accounts
|
|
27869
|
+
* for tool schemas and inlined images the caller cannot easily estimate.
|
|
27870
|
+
*
|
|
27871
|
+
* The ceiling is the caller's when it passes one, because the text/image tier is
|
|
27872
|
+
* graded by model and only the caller knows which model the turn is for; omitted,
|
|
27873
|
+
* the guard resolves the model-less default (or the video tier) itself.
|
|
27874
|
+
*
|
|
27875
|
+
* The error code is CONTEXT_OVERFLOW_CODE, not PROVIDER_ERROR, because naming the
|
|
27876
|
+
* remedy in prose is not the same as being able to act on it: DSH forces a
|
|
27877
|
+
* compaction and retries the same step only for that one code, and every other
|
|
27878
|
+
* 400-shaped failure ends the turn. A byte ceiling is answered by the same
|
|
27879
|
+
* compression a token ceiling is — the conversation shrinks either way — so the
|
|
27880
|
+
* body of the message stays as specific as it was while the code becomes one the
|
|
27881
|
+
* host can recover from.
|
|
27882
|
+
*
|
|
27883
|
+
* @param body the request body about to be serialized and sent.
|
|
27884
|
+
* @param carriesVideo whether the request attaches video, which has its own tier.
|
|
27885
|
+
* @param context what the body-fit loop already did, when it ran.
|
|
27886
|
+
* @param limit the ceiling already resolved for this request's model.
|
|
27887
|
+
* @returns the serialized body, so a caller that is about to send it does not
|
|
27888
|
+
* serialize a body of up to tens of megabytes a second time.
|
|
27889
|
+
*/
|
|
27890
|
+
function assertRequestBodyFits$1(body, carriesVideo = false, context, limit) {
|
|
27677
27891
|
const serialized = JSON.stringify(body);
|
|
27678
27892
|
const bytes = Buffer.byteLength(serialized, "utf8");
|
|
27679
|
-
const
|
|
27680
|
-
if (bytes <=
|
|
27681
|
-
throw new LlmError$1(oversizedBodyMessage(bytes,
|
|
27893
|
+
const ceiling = limit ?? (carriesVideo ? 67108864 : maxMessageBodyBytes$1());
|
|
27894
|
+
if (bytes <= ceiling) return serialized;
|
|
27895
|
+
throw new LlmError$1(oversizedBodyMessage(bytes, ceiling, body, context), CONTEXT_OVERFLOW_CODE);
|
|
27682
27896
|
}
|
|
27683
27897
|
function walkJson(value, visit) {
|
|
27684
27898
|
if (Array.isArray(value)) {
|
|
@@ -27757,6 +27971,8 @@ function createStreamState$4(wire, sessionId) {
|
|
|
27757
27971
|
outputTokens: 0,
|
|
27758
27972
|
cacheReadTokens: 0,
|
|
27759
27973
|
cacheWriteTokens: 0,
|
|
27974
|
+
cacheWrite5mTokens: 0,
|
|
27975
|
+
cacheWrite1hTokens: 0,
|
|
27760
27976
|
reasoningTokens: 0,
|
|
27761
27977
|
sawUsage: false,
|
|
27762
27978
|
toolCallIds: new ToolCallIdNormalizer()
|
|
@@ -27847,8 +28063,10 @@ function processOpenAIStreamLine(line, state) {
|
|
|
27847
28063
|
const prompt = numberOr$7(usage.prompt_tokens, 0);
|
|
27848
28064
|
const details = isRecord$34(usage.prompt_tokens_details) ? usage.prompt_tokens_details : void 0;
|
|
27849
28065
|
const cached = details ? numberOr$7(details.cached_tokens, 0) : 0;
|
|
27850
|
-
|
|
28066
|
+
const written = details ? numberOr$7(details.cache_write_tokens, 0) : 0;
|
|
28067
|
+
state.inputTokens = Math.max(0, prompt - cached - written);
|
|
27851
28068
|
state.cacheReadTokens = cached;
|
|
28069
|
+
state.cacheWriteTokens = written;
|
|
27852
28070
|
state.outputTokens = numberOr$7(usage.completion_tokens, state.outputTokens);
|
|
27853
28071
|
if (isRecord$34(usage.completion_tokens_details)) state.reasoningTokens = numberOr$7(usage.completion_tokens_details.reasoning_tokens, state.reasoningTokens);
|
|
27854
28072
|
}
|
|
@@ -28228,6 +28446,63 @@ function recordDriftCause(cause, sessionId) {
|
|
|
28228
28446
|
function getLastDriftCause(sessionId) {
|
|
28229
28447
|
return driftCauses.get(cacheScopeKey(sessionId));
|
|
28230
28448
|
}
|
|
28449
|
+
/** Last lift per session. */
|
|
28450
|
+
const thinkingCoercions = /* @__PURE__ */ new Map();
|
|
28451
|
+
/**
|
|
28452
|
+
* Record one lift, and make it visible.
|
|
28453
|
+
*
|
|
28454
|
+
* `process.emitWarning` rather than a thrown error or a silently swallowed
|
|
28455
|
+
* value: the request must still go out (that is the whole point of the lift),
|
|
28456
|
+
* but a diagnostic that reaches stderr with a stable code is what keeps it from
|
|
28457
|
+
* being invisible. It is emitted once per turn, and only for a model that
|
|
28458
|
+
* actually declares thinking-only, so a deployment that never asks for 'none'
|
|
28459
|
+
* never sees one.
|
|
28460
|
+
*/
|
|
28461
|
+
function recordThinkingCoercion(coercion, sessionId) {
|
|
28462
|
+
rememberScoped(thinkingCoercions, cacheScopeKey(sessionId), coercion);
|
|
28463
|
+
const target = coercion.to === void 0 ? "the service default" : "\"" + coercion.to + "\"";
|
|
28464
|
+
process.emitWarning("[kimi-code] model \"" + coercion.model + "\" cannot disable thinking; sending " + target + " instead of \"none\" on the " + coercion.wire + " wire.", { code: "KIMI_CODE_THINKING_COERCED" });
|
|
28465
|
+
}
|
|
28466
|
+
/**
|
|
28467
|
+
* Response headers that split a cache write across its two TTL tiers.
|
|
28468
|
+
*
|
|
28469
|
+
* The service states the write TOTAL in 'usage' and the per-tier split only in
|
|
28470
|
+
* these headers, so the split has to be read off the HTTP response — there is no
|
|
28471
|
+
* body field for it. Both are decimal integers; a missing or non-numeric value
|
|
28472
|
+
* means the header said nothing, which is recorded as 0 rather than guessed at
|
|
28473
|
+
* (see KimiCodeCacheStatsDto.cacheWrite5mTokens: an absent header is silence,
|
|
28474
|
+
* not a claim that nothing was written to that tier).
|
|
28475
|
+
*/
|
|
28476
|
+
const CACHE_WRITE_5M_HEADER = "Msh-Usage-Cache-Write-Tokens-5m";
|
|
28477
|
+
const CACHE_WRITE_1H_HEADER = "Msh-Usage-Cache-Write-Tokens-1h";
|
|
28478
|
+
/** Decimal whole-token count from one response header, or 0 when it is silent. */
|
|
28479
|
+
function headerCount(headers, name) {
|
|
28480
|
+
const raw = headers.get(name);
|
|
28481
|
+
if (raw === null) return 0;
|
|
28482
|
+
const text = raw.trim();
|
|
28483
|
+
if (!/^\d+$/.test(text)) return 0;
|
|
28484
|
+
const value = Number(text);
|
|
28485
|
+
return Number.isSafeInteger(value) ? value : 0;
|
|
28486
|
+
}
|
|
28487
|
+
/** The two tier counts one response's headers state. */
|
|
28488
|
+
function cacheWriteTiers(headers) {
|
|
28489
|
+
return {
|
|
28490
|
+
write5m: headerCount(headers, CACHE_WRITE_5M_HEADER),
|
|
28491
|
+
write1h: headerCount(headers, CACHE_WRITE_1H_HEADER)
|
|
28492
|
+
};
|
|
28493
|
+
}
|
|
28494
|
+
/**
|
|
28495
|
+
* File one response's tier counts on the stream state that will close it.
|
|
28496
|
+
*
|
|
28497
|
+
* Called by the adapter on the Response itself, which is the only place the
|
|
28498
|
+
* headers exist; the totals are then filed with the rest of the usage when the
|
|
28499
|
+
* stream closes, so one turn's numbers stay one turn's numbers.
|
|
28500
|
+
*/
|
|
28501
|
+
function applyCacheWriteTiers(state, headers) {
|
|
28502
|
+
const tiers = cacheWriteTiers(headers);
|
|
28503
|
+
state.cacheWrite5mTokens = tiers.write5m;
|
|
28504
|
+
state.cacheWrite1hTokens = tiers.write1h;
|
|
28505
|
+
}
|
|
28231
28506
|
/**
|
|
28232
28507
|
* Rolling cache totals per session.
|
|
28233
28508
|
*
|
|
@@ -28241,7 +28516,9 @@ const EMPTY_CACHE_STATS = {
|
|
|
28241
28516
|
cachedTokens: 0,
|
|
28242
28517
|
freshTokens: 0,
|
|
28243
28518
|
outputTokens: 0,
|
|
28244
|
-
cacheWriteTokens: 0
|
|
28519
|
+
cacheWriteTokens: 0,
|
|
28520
|
+
cacheWrite5mTokens: 0,
|
|
28521
|
+
cacheWrite1hTokens: 0
|
|
28245
28522
|
};
|
|
28246
28523
|
/** Record one request's usage into its own session's totals. */
|
|
28247
28524
|
function recordCacheStats(state, sessionId, accountId) {
|
|
@@ -28253,7 +28530,9 @@ function recordCacheStats(state, sessionId, accountId) {
|
|
|
28253
28530
|
cachedTokens: previous.cachedTokens + state.cacheReadTokens,
|
|
28254
28531
|
freshTokens: previous.freshTokens + state.inputTokens,
|
|
28255
28532
|
outputTokens: previous.outputTokens + state.outputTokens,
|
|
28256
|
-
cacheWriteTokens: previous.cacheWriteTokens + state.cacheWriteTokens
|
|
28533
|
+
cacheWriteTokens: previous.cacheWriteTokens + state.cacheWriteTokens,
|
|
28534
|
+
cacheWrite5mTokens: previous.cacheWrite5mTokens + state.cacheWrite5mTokens,
|
|
28535
|
+
cacheWrite1hTokens: previous.cacheWrite1hTokens + state.cacheWrite1hTokens
|
|
28257
28536
|
});
|
|
28258
28537
|
}
|
|
28259
28538
|
/** Add one entry into an accumulator. */
|
|
@@ -28263,6 +28542,8 @@ function accumulate(totals, stats) {
|
|
|
28263
28542
|
totals.freshTokens += stats.freshTokens;
|
|
28264
28543
|
totals.outputTokens += stats.outputTokens;
|
|
28265
28544
|
totals.cacheWriteTokens += stats.cacheWriteTokens;
|
|
28545
|
+
totals.cacheWrite5mTokens += stats.cacheWrite5mTokens;
|
|
28546
|
+
totals.cacheWrite1hTokens += stats.cacheWrite1hTokens;
|
|
28266
28547
|
}
|
|
28267
28548
|
/**
|
|
28268
28549
|
* Totals for one account's share of a session, one whole session, or every
|
|
@@ -28821,7 +29102,19 @@ var KimiCodeAdapter = class extends LlmAdapter {
|
|
|
28821
29102
|
const entry = catalog.find((model) => model.id === options.model);
|
|
28822
29103
|
const normalized = normalizeGenerateOptions(options);
|
|
28823
29104
|
const images = await resolveRequestImages$1(normalized, this.options.attachments, signal);
|
|
28824
|
-
const
|
|
29105
|
+
const imageTrimmed = offloadOldestRequestImages$1(normalized, maxRequestImageBytes$1(), images);
|
|
29106
|
+
const gatedEffort = coerceThinkingEffort(options.model, mapReasoningEffort(options.reasoningEffort === void 0 || options.reasoningEffort === null ? void 0 : String(options.reasoningEffort)));
|
|
29107
|
+
if (gatedEffort.coercedFrom !== null) recordThinkingCoercion({
|
|
29108
|
+
model: options.model,
|
|
29109
|
+
wire,
|
|
29110
|
+
from: gatedEffort.coercedFrom,
|
|
29111
|
+
to: gatedEffort.effort
|
|
29112
|
+
}, options.sessionId);
|
|
29113
|
+
const videoTrimmed = offloadOldestRequestVideos(imageTrimmed, MAX_REQUEST_VIDEO_BYTES$1);
|
|
29114
|
+
const requestOptions = gatedEffort.effort === void 0 ? videoTrimmed : {
|
|
29115
|
+
...videoTrimmed,
|
|
29116
|
+
reasoningEffort: ReasoningEffortId(gatedEffort.effort)
|
|
29117
|
+
};
|
|
28825
29118
|
const videos = await resolveRequestVideos(requestOptions, this.options.videos, signal);
|
|
28826
29119
|
const settings = await this.settings();
|
|
28827
29120
|
const media = {
|
|
@@ -28839,7 +29132,7 @@ var KimiCodeAdapter = class extends LlmAdapter {
|
|
|
28839
29132
|
maxTokens: clampOutputToContext$1(requestedMax, promptLimit, estimatedInputTokens(requestOptions))
|
|
28840
29133
|
};
|
|
28841
29134
|
const carriesVideo = requestHasVideo(requestOptions);
|
|
28842
|
-
const bodyLimit = carriesVideo ? MAX_VIDEO_MESSAGE_BODY_BYTES :
|
|
29135
|
+
const bodyLimit = carriesVideo ? MAX_VIDEO_MESSAGE_BODY_BYTES : maxRequestBodyBytesFor(kimiCodeModelDef(entry?.id ?? options.model), process.env);
|
|
28843
29136
|
let buildOptions = boundedOptions;
|
|
28844
29137
|
let body = "";
|
|
28845
29138
|
for (let attempt = 0;; attempt++) {
|
|
@@ -28853,12 +29146,12 @@ var KimiCodeAdapter = class extends LlmAdapter {
|
|
|
28853
29146
|
excessBytes: bytes - bodyLimit
|
|
28854
29147
|
});
|
|
28855
29148
|
if (attempt > MAX_BODY_FIT_ATTEMPTS || !requestHasSendableImage(buildOptions, images)) {
|
|
28856
|
-
assertRequestBodyFits$1(built, carriesVideo, context());
|
|
29149
|
+
assertRequestBodyFits$1(built, carriesVideo, context(), bodyLimit);
|
|
28857
29150
|
throw new Error("unreachable: assertRequestBodyFits returns or throws");
|
|
28858
29151
|
}
|
|
28859
29152
|
const drop = dropOldestImagesUntilFits(buildOptions, images, bytes - bodyLimit, requestOptions);
|
|
28860
29153
|
if (drop.dropped === 0) {
|
|
28861
|
-
assertRequestBodyFits$1(built, carriesVideo, context());
|
|
29154
|
+
assertRequestBodyFits$1(built, carriesVideo, context(), bodyLimit);
|
|
28862
29155
|
throw new Error("unreachable: assertRequestBodyFits returns or throws");
|
|
28863
29156
|
}
|
|
28864
29157
|
buildOptions = drop.options;
|
|
@@ -28934,6 +29227,7 @@ var KimiCodeAdapter = class extends LlmAdapter {
|
|
|
28934
29227
|
const reader = response.body.getReader();
|
|
28935
29228
|
const decoder = new TextDecoder();
|
|
28936
29229
|
const state = createStreamState$4(wire, requestOptions.sessionId);
|
|
29230
|
+
applyCacheWriteTiers(state, response.headers);
|
|
28937
29231
|
markSessionActive(requestOptions.sessionId);
|
|
28938
29232
|
let buffer = "";
|
|
28939
29233
|
/**
|
|
@@ -29399,7 +29693,9 @@ function cacheStatsOrNull(sessionId) {
|
|
|
29399
29693
|
return {
|
|
29400
29694
|
...stats,
|
|
29401
29695
|
...lastDrift === void 0 ? {} : { lastDrift },
|
|
29402
|
-
|
|
29696
|
+
cacheWriteTokens: stats.cacheWriteTokens,
|
|
29697
|
+
cacheWrite5mTokens: stats.cacheWrite5mTokens,
|
|
29698
|
+
cacheWrite1hTokens: stats.cacheWrite1hTokens
|
|
29403
29699
|
};
|
|
29404
29700
|
}
|
|
29405
29701
|
/**
|
|
@@ -29992,7 +30288,7 @@ async function assertVideoCapableRoute(ctx, exec, source) {
|
|
|
29992
30288
|
const llm = ctx.get("llm");
|
|
29993
30289
|
if (llm === void 0) throw new HarnessError(`cannot attach "${source}": the LLM service is unavailable`, "KIMI_VIDEO_NO_LLM");
|
|
29994
30290
|
const active = await llm.resolveModelInfo(provider, model, exec.signal);
|
|
29995
|
-
if (active.inputModalities === void 0 || !active.inputModalities.includes("video")) throw new HarnessError(`cannot attach "${source}": model "${model}" does not accept video input; switch to k3 or kimi-for-coding`, "KIMI_VIDEO_MODEL_UNSUPPORTED");
|
|
30291
|
+
if (active.inputModalities === void 0 || !active.inputModalities.includes("video")) throw new HarnessError(`cannot attach "${source}": model "${model}" does not accept video input; switch to k3, k3.1-pro, kimi-for-coding or kimi-for-coding-highspeed`, "KIMI_VIDEO_MODEL_UNSUPPORTED");
|
|
29996
30292
|
}
|
|
29997
30293
|
function humanBytes$1(bytes) {
|
|
29998
30294
|
return bytes < 1024 * 1024 ? `${(bytes / 1024).toFixed(1)} KB` : `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
@@ -30055,7 +30351,7 @@ function createKimiVideoTool(ctx, options = {}) {
|
|
|
30055
30351
|
const fetchFn = options.fetchFn ?? fetch;
|
|
30056
30352
|
return defineTool({
|
|
30057
30353
|
name: KIMI_VIDEO_TOOL_NAME,
|
|
30058
|
-
description: "Attach a video to the conversation for models that accept video input (Kimi k3 and kimi-for-coding). Use this when the user asks about a video file or a video URL: pass an absolute local path or an http(s) URL. The video is sent to the model on the next request; it does not work on image-only models such as k3-256k.",
|
|
30354
|
+
description: "Attach a video to the conversation for models that accept video input (Kimi k3, k3.1-pro, kimi-for-coding and kimi-for-coding-highspeed). Use this when the user asks about a video file or a video URL: pass an absolute local path or an http(s) URL. The video is sent to the model on the next request; it does not work on image-only models such as k3-256k.",
|
|
30059
30355
|
parameters: {
|
|
30060
30356
|
source: {
|
|
30061
30357
|
type: "string",
|