@eddyskywalker/dsh-chatgpt-subscription 0.3.0 → 0.3.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 +26 -0
- package/lib/client.js +11 -5
- package/lib/client.js.map +1 -1
- package/lib/index.js +484 -22
- package/lib/types/client/kimi-code/KimiModelCapabilities.d.ts.map +1 -1
- package/lib/types/client/kimi-code/locales.d.ts +12 -6
- package/lib/types/client/kimi-code/locales.d.ts.map +1 -1
- package/lib/types/client/kimi-code/styles.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 +12 -0
- package/lib/types/host/kimi-code/client.d.ts.map +1 -1
- package/lib/types/host/kimi-code/mapper.d.ts +38 -2
- package/lib/types/host/kimi-code/mapper.d.ts.map +1 -1
- package/lib/types/host/kimi-code/video-store.d.ts +99 -0
- package/lib/types/host/kimi-code/video-store.d.ts.map +1 -0
- package/lib/types/host/kimi-code/video-tool.d.ts +25 -0
- package/lib/types/host/kimi-code/video-tool.d.ts.map +1 -0
- package/lib/types/index.d.ts.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -70,6 +70,32 @@
|
|
|
70
70
|
- 声明所在 system 消息**同时带有文本**时不再静默丢弃:服务的动态工具 schema 没有 `content` 字段,两者无法合成一条消息,因此现在保留文本(另发一条),并把声明替换为明确的说明消息,而不是让工具无声消失。
|
|
71
71
|
- **按官方 CLI 的能力表逐模型修正两项能力**(依据 `managed:kimi-code` 托管模型表里每个模型的 `capabilities` 列表):`k3` = image_in + video_in + dynamically_loaded_tools;`k3-256k` = image_in + **dynamically_loaded_tools**(无 video);`kimi-for-coding` = image_in + video_in + **dynamically_loaded_tools**;`kimi-for-coding-highspeed` = image_in + video_in(**无** dynamically_loaded_tools)。修正了先前把 `dynamically_loaded_tools` 当成「K3 独有」的推导错误——官方线文档只提 K3 是因为它描述的是 K3 的请求 schema,而 CLI 自己的能力表把它也标给了 K2.8 Preview。
|
|
72
72
|
- 修正能力判定与官方表格的一致性(已对照 https://www.kimi.com/code/docs/en/kimi-code/models.html 逐项核对):`k3` 与 `kimi-for-coding` 为「Image, video」、`k3-256k` 为「Image only」,与内置表一致;`kimi-for-coding-highspeed` 官方标为 K2.7 Code HighSpeed,「Thinking: ON」且无可选档位,故其固有档位仍按官方标注为 `high`。
|
|
73
|
+
- 按第二轮审计修正视频入口的几处问题:
|
|
74
|
+
- **`.mkv` 能存不能发**:入口白名单收 `.mkv`(存为 `video/x-matroska`)而 mapper 的 `isVideoMediaType` 不含它,导致用户挂载 mkv 会收到「Attached video ✅」,模型却只拿到 `unsupported-container` 占位文本。现在入口**只接受 mapper 真能发出的容器**(即 `KIMI_VIDEO_MEDIA_TYPES`),mkv 在入口即被拒绝并说明——入口承诺与线上行为从此是同一件事。
|
|
75
|
+
- **`e2e` 注释的覆盖声称超出实际**:该测试直调 `buildOpenAIRequest`,从不经过 DSH 真实管道。注释已改为如实说明「覆盖请求映射阶段 + 安装版运行时的内容助手」,并明确列出**未**覆盖的部分(会话持久化 / compaction / transcript),要求装机实测。过程中还发现一个值得记录的事实:本仓库**安装版 `@deepseek-ai/dsh-llm` 是 0.1.1-rc.2**(根 barrel 只导出 `contentHasImage` / `projectImagesForTextModel`,**完全没有** file 投影),而工作区 checkout 是 0.1.5-rc.1——两者不是同一份代码,断言已改为针对实际运行的那份。
|
|
76
|
+
- **视频存储新增回收**:内容寻址让重复挂载免费,但此前没有任何清理,目录只会增长。现在写入时按 mtime 做 LRU 回收(预算 512 MB,best-effort、失败不影响挂载),并顺带清理崩溃写入残留的 `.tmp.*` 文件。
|
|
77
|
+
- 顺带修掉两处小瑕疵:`video-tool.ts` 自己写的 DNS `lookup` 改为复用 `fetch-address-policy.ts` 已有的 `lookupHostAddresses`(避免语义漂移);`index.ts` 中 `disposeVideoTool()` 的缩进与相邻一致。
|
|
78
|
+
- **视频输入打通了入口**:此前只有一条没有生产者的 mapper 路径(能力表也只能标注「无上传入口」)。现在新增两件东西,让视频端到端可达:
|
|
79
|
+
- `kimi_attach_video` 工具(`src/host/kimi-code/video-tool.ts`):接受**本地绝对路径**或 **http(s) 链接**,把视频字节交给插件的视频存储,再以 `exec.deferContext()` 注入一条 plugin 来源的 user 消息(与本插件已有的图片工具同一机制,**不需要改动 DSH**)。可选 `question` 参数让模型在同一轮就视频作答。
|
|
80
|
+
- 视频本地存储(`src/host/kimi-code/video-store.ts`):DSH 的附件服务只存图片,因此本线路自带存储。标识取字节 sha256(重复挂载同一文件幂等),读取时**重新校验摘要**,被篡改或截断的对象会被拒绝而不是当成原文件发出去。
|
|
81
|
+
- **尺寸上限取官方依据**:官方视频集成把本地文件编码为 `data:video/...;base64,...` 并限制该载荷约 **50 MB**(且明确说这是其客户端上限、非 Kimi API 上限),VS Code 端文件选择器限 **20 MB**。前者描述的是「这个 wire 上模型接受什么」,故上限设为略低于它的 **30 MB 原始字节**(base64 增长 4/3,所以编码后正好落在 40 MB,留在 50 MB 之下)。
|
|
82
|
+
- **两个安全/正确性闸门**:URL 来源在发起请求**之前**套用与搜索抓取 provider 相同的公网地址策略(否则该工具会成为一个 SSRF 原语——测试里有一条专门证明策略缺失时用例会失败);且只有当**当前会话路由到 `kimi-code` 且所选模型声明了 video** 时才允许挂载,否则明确拒绝并给出补救(换 k3 / kimi-for-coding),绝不会把别的适配器没有处理分支的块注入进去。
|
|
83
|
+
- 能力表脚注相应改为「视频需先用 kimi_attach_video 挂载;直接粘贴仍只支持图片」。
|
|
84
|
+
- 新增 `test/kimi-code-video-tool.test.ts`(17 条:容器识别、内容寻址与幂等、超限/空文件/类型拒绝、摘要失配与文件缺失、相对路径/未知扩展名/非视频模型/错误 provider 的拒绝、私网 URL 拒绝且**不发出请求**)与 `test/kimi-code-video-e2e.test.ts`(3 条:从落盘文件解析出字节并确认线上是真实 base64 内容、字节缺失时降级为可读文本、无视频请求不受影响)。
|
|
85
|
+
- **修复审查发现的问题**(视频与动态工具):
|
|
86
|
+
- **live 目录现在真的能关掉能力**:`parseCatalogModel` 原先把 `supports_dynamic_tools === true` 之外的一切都当作「字段缺席」,于是服务端显式返回 `false` 时会回退到内置表、照样显示支持——与 `model-catalog.ts` 注释里「live 列表权威、包括可以关掉」的承诺自相矛盾。现按三态解析(`true` / `false` / 缺席),显式 `false` 穿透回退。
|
|
87
|
+
- **卡片与请求路径统一到一个解析入口** `dynamicToolsForEntry()`:此前卡片会回退内置表而请求路径 (`entry?.supportsDynamicTools === true`) 不会,导致在线但 `/models` 未返回该字段时 **UI 显示支持、实际请求却降级为「模型不支持」**,且行为随网络状态翻转;离线反而正常。现在两处共用同一函数。
|
|
88
|
+
- **声明不再随持久化丢失**:`withMessageTools` 原先把声明只挂在 `Symbol` 上且 `enumerable: false`,而 DSH 会话历史经 JSON 持久化必然丢掉符号键——会话恢复后声明会静默消失,模型会「以为自己有工具但请求里没有」。现在同时写入一个普通字符串键 `kimiCodeMessageTools`(可被 JSON 序列化,但仍非枚举,兄弟线路照样看不见),并新增 `rehydrateMessageTools()` 供恢复后重新挂上符号。
|
|
89
|
+
- **不再重复发送 system 文本**:`leadingSystemText` 折叠所有 system 文本到请求开头,而声明槽位又会在原位置重发一次,同一段文本出现两遍(浪费 token,且第二次位置可能扰动本想保护的缓存前缀)。现在 `leadingSystemText` 跳过带声明的消息,文本只在声明位置出现一次。
|
|
90
|
+
- **Anthropic 线路不再静默吞掉声明**:该协议不支持消息级声明,原本直接丢弃且无任何提示,模型可能调用从未声明的工具。现在把未发送数量写进 `system` 提示。
|
|
91
|
+
- **请求体守卫不再二次序列化、也不再被用户文本欺骗**:原先用 `JSON.stringify(body).includes('"video_url"')` 判断是否带视频——body 可达数十 MB 却被序列化两次,且用户消息里只要出现该字面量就会把 2 MB 守卫放宽到 64 MB。现由调用方显式传 `carriesVideo`(复用已有的 `requestHasVideo`)。
|
|
92
|
+
- **不再超前宣称视频能力**:模型确实接受视频,但本插件与 DSH 的附件服务都没有视频生产者/读取者(`videos` 读取器从未在 `src/index.ts` 注入),实际永远走 `unreadable` 占位。能力表因此把标签标为「视频*」并加脚注说明当前版本没有上传入口、不会发出视频内容块,避免 UI 承诺与实际可达路径不符。
|
|
93
|
+
- 清理 `classifyKimiFailure` 中 `isLimit ? 'PROVIDER_ERROR' : 'PROVIDER_ERROR'` 的死三元(两分支同值,读起来像意图未实现)。
|
|
94
|
+
- **修复上一轮修复引入的回归**:`leadingSystemText` 是两条 wire 共用的,跳过声明载体后,只有 OpenAI 路径会在载体原位置重发文本;Anthropic 路径因此**整段丢失载体文本**(只剩工具数量提示),恰好违反 `declarationSlots` 注释里「丢掉 system 文本会静默改变模型收到的信息」这条原则。现在 Anthropic 路径会把载体文本拼回 `system`(排在 notice 之前),并加了 2 条回归用例——其中顺序断言特意先 `>= 0` 再比较,否则文本缺失时 `indexOf` 返回 -1 会让断言**空过**。
|
|
95
|
+
- 顺手清理审查指出的三处小瑕疵:`classifyKimiFailure` 中删掉三元后遗留的未引用 `isLimit`(改为真正参与文案选择的 `limitReached`);`client.ts` 里错位堆在 `dynamicToolsForEntry` 上方的「Input modalities」注释归位;`withMessageTools` 的注释原先一边说「非枚举所以其他读者看不到」一边字符串键副本是 `enumerable: true`,改为明确写清两个副本可见性不同及其原因。
|
|
96
|
+
- `assertRequestBodyFits` 现在**返回**它序列化出的 body,供适配器直接复用:此前带视频时同一个数十 MB 的 body 会被 `JSON.stringify` 两次。
|
|
97
|
+
- 新增 `test/kimi-code-review-fixes.test.ts`逐条钉住上述缺陷:显式 `false` 生效、三态回退边界、文本只出现一次、Anthropic 提示、守卫不被文本欺骗、声明经 JSON 往返后仍可发送;`test/kimi-code-capability-ui.test.tsx` 增加脚注相关 1 条。
|
|
98
|
+
|
|
73
99
|
- **重排模型能力展示**:此前把能力说明当成长句塞在模型名那一列,把名称列撑开、右侧描述错位。现改为独立的四列表格(模型 / 多模态 / 动态工具 / 说明):能力只显示短标签(视频 / 仅图片 / 动态工具 / —),逐模型的协议、默认思考档位与所需套餐移入悬停提示;表格自身不再附带任何解释段落。表格抽成可测组件 `KimiModelCapabilities`(`src/client/kimi-code/KimiModelCapabilities.tsx`),新增 `test/kimi-code-capability-ui.test.tsx`(5 条)钉住列数、每模型一行、长句不得进入单元格、悬停内容,以及说明为空时不渲染 `null`。该表也**不再依赖 `description` 是否存在**——实时目录条目缺描述时整个表格(含能力)仍渲染。
|
|
74
100
|
- 澄清并测试这两项能力的**跨模型隔离**:机制本身有三重隔离——符号载体**不可枚举**(其他线路的序列化器看不到它)、映射器只在 `messageTools === true` 时输出、且声明只存在于 Kimi 的 OpenAI 线路映射中。新增 `test/kimi-code-capability-isolation.test.ts`(6 条):Command Code 各模型仍不含 video(证明模块增强是**纯类型、不产生运行时值**)、Kimi 四个模型 id 的 video 与 dynamically_loaded_tools 与官方能力表**逐项**一致(并断言两者并非同一集合:HighSpeed 有 video 却无动态工具)、视频块不会出现在兄弟线路的请求体里、同一段历史里的声明也不会被兄弟线路带出去。
|
|
75
101
|
- 另记录一个**证据取舍**:公共 `models.dev` 目录虽声明了 `dynamically_loaded_tools` 字段,但 Moonshot 自家四个条目均未标注,故本插件**不采信该目录**,改以官方 CLI 托管模型表的 `capabilities` 为准;运行时仍以实时 `/v1/models` 的 `supports_dynamic_tools` / `supports_video_in` 覆盖内置表。
|
package/lib/client.js
CHANGED
|
@@ -2813,10 +2813,11 @@ window.__ModuleLoader__.load({
|
|
|
2813
2813
|
unselectAll: "全不选",
|
|
2814
2814
|
wireAnthropic: "Anthropic",
|
|
2815
2815
|
wireOpenai: "OpenAI",
|
|
2816
|
-
capVideo: "
|
|
2816
|
+
capVideo: "视频*",
|
|
2817
2817
|
capDynamicTools: "动态工具",
|
|
2818
2818
|
capImageOnly: "仅图片",
|
|
2819
2819
|
capNone: "—",
|
|
2820
|
+
capVideoFootnote: "* 视频输入需先由 kimi_attach_video 工具挂载(本地绝对路径或 http(s) 链接);直接粘贴的上传路径仍只支持图片。",
|
|
2820
2821
|
capabilitiesTitle: "模型能力",
|
|
2821
2822
|
capColMedia: "多模态",
|
|
2822
2823
|
capColTools: "动态工具",
|
|
@@ -2923,10 +2924,11 @@ window.__ModuleLoader__.load({
|
|
|
2923
2924
|
unselectAll: "Deselect all",
|
|
2924
2925
|
wireAnthropic: "Anthropic",
|
|
2925
2926
|
wireOpenai: "OpenAI",
|
|
2926
|
-
capVideo: "Video",
|
|
2927
|
+
capVideo: "Video*",
|
|
2927
2928
|
capDynamicTools: "Dynamic tools",
|
|
2928
2929
|
capImageOnly: "Images",
|
|
2929
2930
|
capNone: "—",
|
|
2931
|
+
capVideoFootnote: "* Video input is attached with the kimi_attach_video tool (an absolute local path or an http(s) URL); the paste/upload path still accepts images only.",
|
|
2930
2932
|
capabilitiesTitle: "Capabilities",
|
|
2931
2933
|
capColMedia: "Multimodal",
|
|
2932
2934
|
capColTools: "Dynamic tools",
|
|
@@ -2999,9 +3001,9 @@ window.__ModuleLoader__.load({
|
|
|
2999
3001
|
*/
|
|
3000
3002
|
const t = zh$1;
|
|
3001
3003
|
function KimiModelCapabilities({ models }) {
|
|
3002
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.
|
|
3004
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3003
3005
|
className: "dsha-cap-table",
|
|
3004
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("table", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("thead", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tr", { children: [
|
|
3006
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("table", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("thead", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tr", { children: [
|
|
3005
3007
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", { children: t.capabilitiesTitle }),
|
|
3006
3008
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", { children: t.capColMedia }),
|
|
3007
3009
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", { children: t.capColTools }),
|
|
@@ -3033,7 +3035,10 @@ window.__ModuleLoader__.load({
|
|
|
3033
3035
|
children: model.description ?? ""
|
|
3034
3036
|
})
|
|
3035
3037
|
] }, model.id);
|
|
3036
|
-
}) })] })
|
|
3038
|
+
}) })] }), models.some((model) => model.supportsVideo) && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
3039
|
+
className: "dsha-muted dsha-cap-footnote",
|
|
3040
|
+
children: t.capVideoFootnote
|
|
3041
|
+
})]
|
|
3037
3042
|
});
|
|
3038
3043
|
}
|
|
3039
3044
|
//#endregion
|
|
@@ -4723,6 +4728,7 @@ window.__ModuleLoader__.load({
|
|
|
4723
4728
|
.dsha-cap-on{color:var(--dsw-alias-label-primary);font-weight:500}
|
|
4724
4729
|
.dsha-cap-off{color:var(--dsw-alias-label-tertiary)}
|
|
4725
4730
|
.dsha-cap-notes{line-height:1.5;min-width:200px}
|
|
4731
|
+
.dsha-cap-footnote{font-size:11px;line-height:1.55;margin:8px 0 0}
|
|
4726
4732
|
`;
|
|
4727
4733
|
/** Kimi-specific rules layered on top of the shared control styles. */
|
|
4728
4734
|
function installKimiCodeStyles() {
|