Skip to content

Commit f433f3d

Browse files
committed
refactor(kimi-native-tools): unify image resize filter with the engine codec
- the two Rust codecs' only remaining drift was the resize filter (native Triangle/jimp-parity vs engine Lanczos3); EXIF orientation and alpha handling were already equivalent with test coverage - native fit_within_edge now uses Lanczos3, matching the engine media pipeline (kimi-agent media/image.rs) so both paths produce identical output; the jimp-parity filter is retired with the TS host - migration plan §8 records the merge evaluation: shared-core extraction is not worth the image dependency in kimi-shared
1 parent b62e61f commit f433f3d

2 files changed

Lines changed: 9 additions & 7 deletions

File tree

CODEX_MIGRATION_PLAN.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,8 @@ kimi-sdk(Session 45/45 + Harness + catalog 归一化 + config/errors + /btw)
247247
- **`prompt_cache_key` Moonshot 专属**:仅官方端点(api.moonshot.ai / *.moonshot.ai)发送,非 Moonshot 端点不发(真实 400 修复,对齐上游)
248248
- **GitHub 工具族**:29 工具已移植(表驱动 + reqwest + 审批白名单);**Workflow 不补**(Rust background+Swarm 已覆盖)
249249
- **kosong 不搬运**:三协议 + SSE + 重试 + prompt_cache_key + usage 引擎已独立覆盖;独有缺口(kimi-schema $ref 规范化已移植、anthropic-profile 已复制本地化、kimi-files/capability/Astron 数据项)随 node-sdk 退役
250-
- **image 不迁 kimi-sdk**:压缩核心已两处 Rust(native codec + engine media pipeline);TS 退役后以 native codec 为基准合并(两套 Rust 压缩已 drift:EXIF/Triangle vs Lanczos3/alpha)
250+
- **image 不迁 kimi-sdk**:压缩核心已两处 Rust(native codec + engine media pipeline)。**2026-08-10 合并评估定案:保留两套**——EXIF 已对齐(native `decode_with_orientation` 与 engine `apply_exif_orientation` 均为 image crate `apply_orientation`,等价实现 + 双方测试锁定);alpha 均保留(PNG/WebP 走 RGBA,仅 JPEG 分支转 RGB);唯一差异为滤波算法(native Triangle=jimp 历史基准 vs engine Lanczos3=质量优先),**有意取舍非 drift**;共享核心下沉 kimi-shared 需 image 依赖 + 行为对拍,成本>收益,不做
251+
- **summarizer 双通道** ✅ 已补(2026-08-10):`LlmCompactionDelegate``HostLlmProxy` 支持 host-proxy 会话(原报 `compaction.unable`);SDK 的 `agent.nativeLlmProvider` opt-in 接线保留(主回合语义不变)
251252
- **compaction 同步语义**:引擎 compact 是同步 RPC,无 in-flight 可取消 → `session/cancel_compact` no-op(契约注释早已承诺,2026-08-10 补注册)
252253
- **summarizer 仅 native LLM**:host-proxy 会话 compact 报 `compaction.unable`(SDK 精确映射);summarizer 独立通道是引擎设计缺口(§1.4.1),SDK 已按 `agent.nativeLlmProvider` 显式 opt-in 接线
253254
- **kimi-sdk `set_question_handler` 不实现**(2026-08-10 定案):引擎 AskUserQuestion 工具已改为"格式化内容 + stop_turn + 答案作为下一条消息"(`tools/ask_user.rs`),无反向 RPC;question 面由该机制覆盖

packages/kimi-native-tools/src/image_compress.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ pub fn crop_image(
311311
// ── internals ────────────────────────────────────────────────────────────
312312

313313
/// Pre-multiply alpha into the RGB channels so fully transparent pixels
314-
/// contribute zero color during resize. Without this, the Triangle filter
314+
/// contribute zero color during resize. Without this, the resize filter
315315
/// blends the RGB values of transparent pixels into their visible neighbors,
316316
/// producing visible color fringes on edges with alpha.
317317
fn premultiply_alpha(img: &mut DynamicImage) {
@@ -354,10 +354,11 @@ fn unpremultiply_alpha(img: &mut DynamicImage) {
354354
}
355355

356356
/// Scale `img` so its longest edge is at most `edge`, preserving aspect
357-
/// ratio. No-op (returns false) when the image already fits. Uses Triangle
358-
/// (bilinear) filtering which covers all source pixels during downscaling —
359-
/// no aliasing on text or fine patterns. Pre-multiplies alpha before
360-
/// resizing to prevent color bleed from transparent pixels.
357+
/// ratio. No-op (returns false) when the image already fits. Uses Lanczos3 —
358+
/// matching the engine media pipeline (`kimi-agent` `media/image.rs`) so both
359+
/// Rust codecs produce identical output; the historical jimp-parity Triangle
360+
/// filter is retired with the TS host. Pre-multiplies alpha before resizing
361+
/// to prevent color bleed from transparent pixels.
361362
fn fit_within_edge(img: &mut DynamicImage, edge: u32) -> bool {
362363
let (w, h) = img.dimensions();
363364
let longest = w.max(h);
@@ -371,7 +372,7 @@ fn fit_within_edge(img: &mut DynamicImage, edge: u32) -> bool {
371372
if had_alpha {
372373
premultiply_alpha(img);
373374
}
374-
*img = img.resize_exact(new_w, new_h, image::imageops::FilterType::Triangle);
375+
*img = img.resize_exact(new_w, new_h, image::imageops::FilterType::Lanczos3);
375376
if had_alpha {
376377
unpremultiply_alpha(img);
377378
}

0 commit comments

Comments
 (0)