Skip to content

feat: FetchURL tool supports downloading images#1499

Open
bj456736 wants to merge 1 commit into
MoonshotAI:mainfrom
bj456736:feat/fetch-url-image-support
Open

feat: FetchURL tool supports downloading images#1499
bj456736 wants to merge 1 commit into
MoonshotAI:mainfrom
bj456736:feat/fetch-url-image-support

Conversation

@bj456736

@bj456736 bj456736 commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

问题概述

FetchURL 工具目前只能获取文本内容,无法处理图片。当用户尝试用 FetchURL 拉取图片 URL 时,工具会尝试解析 HTML 并提取文本,导致图片内容丢失。

解决方案要点

  1. 检测图片内容类型:在 LocalFetchURLProvider 中检查响应头的 Content-Type,识别 image/* 类型。
  2. 读取二进制内容:对图片请求,读取 binary body 并转换为 base64 data URI。
  3. 返回 vision-ready 格式:将图片以 ContentPart[] 格式返回,包含 image_url 字段,供 LLM vision 模型直接使用。
  4. 更新工具描述:在 fetch-url.md 中补充说明工具现在支持图片下载。
  5. 增加测试:为图片获取功能添加单元测试,覆盖工具层和 provider 层。

技术方案选择原因

  • 直接复用现有架构:在 LocalFetchURLProvider 中扩展,不引入新依赖,保持工具自包含。
  • base64 data URI 方案:避免引入外部存储,图片内联在消息中,兼容所有 LLM provider。
  • 向后兼容:文本内容类型(text/html, application/json 等)保持原有行为不变。
  • sniff 图片尺寸:当响应包含 Content-Length 时记录尺寸信息,便于调试。

PR 链接

https://github.com/MoonshotAI/kimi-code/pull/NEW


Commit: 659898e
Branch: feat/fetch-url-image-support

- Detect image/* content types in LocalFetchURLProvider
- Read binary body for images, convert to base64 data URI
- Sniff image dimensions when available
- Return image as ContentPart[] with image_url for LLM vision models
- Update tool description to mention image support
- Add tests for image fetching in both tool and provider
@changeset-bot

changeset-bot Bot commented Jul 8, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 659898e

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 659898e52c

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

};
}

if (kind === 'image') {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Route image URLs around the Moonshot text fetcher

In configurations with services.moonshot_fetch.base_url, createRuntimeConfig wraps the local fetcher in MoonshotFetchURLProvider, and that provider returns { content, kind: 'extracted' } for every 200 from the coding-fetch service (packages/agent-core/src/tools/providers/moonshot-fetch-url.ts:51-56). This image branch is therefore only reached when the service fails and falls back locally, so a successful Moonshot fetch of an image URL produces text/empty output instead of an image even though FetchURL now advertises image support. Detect image responses before/inside the Moonshot path or have that provider surface kind: 'image'.

Useful? React with 👍 / 👎.

const output: ContentPart[] = [
{ type: 'text', text: `<system>${systemParts.join(' ')}</system>` },
{ type: 'text', text: `<image url="${args.url}">` },
{ type: 'image_url', imageUrl: { url: content } },

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Gate image tool output on image-capable models

When the current model lacks image_in, FetchURL is still registered whenever a urlFetcher exists (packages/agent-core/src/agent/tool/index.ts:421), unlike ReadMediaFileTool which is capability-gated. Returning an image_url here records media in the tool result; providers such as the OpenAI legacy adapter then reattach tool-result images as image_url user content on the next request (packages/kosong/src/providers/openai-legacy.ts:260-267), which text-only tool-capable models reject. Return a text error or only advertise/emit image output when image_in is supported.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant