Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/cap-read-output.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@moonshot-ai/kimi-code": patch
---

A single file read by the agent now returns at most 100,000 characters or about 25,000 tokens, whichever comes first, instead of up to 500,000 characters; set `max_chars` under `[read]` in config.toml to raise both limits again.
6 changes: 3 additions & 3 deletions docs/en/configuration/config-files.md
Original file line number Diff line number Diff line change
Expand Up @@ -452,15 +452,15 @@ Like the `tools` / `disallowedTools` fields of an agent file, this section shape
| Field | Type | Default | Description |
| --- | --- | --- | --- |
| `default_max_chars` | `integer` | `100000` | Character budget when the tool call omits `max_chars` |
| `max_chars` | `integer` | `500000` | Maximum character budget a tool call may request |
| `max_chars` | `integer` | `100000` | Maximum character budget a tool call may request |

```toml
[read]
default_max_chars = 100000
max_chars = 500000
max_chars = 100000
```

Both values must be positive integers. A call's `max_chars` overrides the default, but is capped at the configured maximum; the result reports the effective budget. If the configured default exceeds the maximum, the maximum also limits default reads. Raise `default_max_chars` when you want larger documents to be returned in one call without the agent requesting a larger budget.
Both values must be positive integers. A call's `max_chars` overrides the default, but is capped at the configured maximum; the result reports the effective budget. If the configured default exceeds the maximum, the maximum also limits default reads. Each call also stops at about `max_chars` / 4 estimated tokens, counting one token per non-ASCII character and per four ASCII characters, so text with many non-ASCII characters, such as Chinese, returns fewer characters per call. Raise `max_chars` to let a call return more than 100000 characters or about 25000 tokens, and raise `default_max_chars` as well when you want larger documents to be returned in one call without the agent requesting a larger budget.

## `image`

Expand Down
4 changes: 2 additions & 2 deletions docs/en/reference/tools.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ File tools handle reading, writing, and searching the local filesystem — the f
| `Glob` | Auto-allow | Find files by glob pattern |
| `ReadMediaFile` | Auto-allow | Read an image or video file |

**`Read`** accepts a file path (`path`) plus optional `line_offset` (starting line number; negative values count from the end), `column_offset` (zero-based position within the first line of a forward read), `n_lines` (requested number of source lines), and `max_chars` (maximum characters in the result, including line numbers and status). Omitting `n_lines` reads toward the end of the file. The default is 100,000 characters, and calls can request up to 500,000; both values can be changed in the [`read` configuration](../configuration/config-files.md#read). Characters and column offsets use JavaScript string length in the displayed text, excluding the line-number prefix for column offsets: common letters and Chinese characters count as one, while many emoji count as two.
**`Read`** accepts a file path (`path`) plus optional `line_offset` (starting line number; negative values count from the end), `column_offset` (zero-based position within the first line of a forward read), `n_lines` (requested number of source lines), and `max_chars` (maximum characters in the result, including line numbers and status). Omitting `n_lines` reads toward the end of the file. The default and the most a call can request are both 100,000 characters, and a call also stops at about a quarter of the maximum in estimated tokens (25,000 by default), so text with many non-ASCII characters, such as Chinese, returns fewer characters per call; both values can be changed in the [`read` configuration](../configuration/config-files.md#read). When a call names a range, with `n_lines` or a negative `line_offset`, and the lines that fit within `max_chars` still exceed the token limit, `Read` returns an error that suggests a range that fits instead of returning part of it; a range cut short only by `max_chars` still returns a page with `Next Read` arguments. Characters and column offsets use JavaScript string length in the displayed text, excluding the line-number prefix for column offsets: common letters and Chinese characters count as one, while many emoji count as two.

`Read` prefers complete lines and its results are not shortened again by the general tool-output limit. A line that cannot fit on its own page is returned in fragments; the status reports the column range and `Next Read` arguments to retrieve the rest without raising the budget. Join fragments of the same line without adding a newline. A partial line remains in the requested `n_lines` range until its ending is returned. Invalid column positions return an error rather than skipping content.
`Read` prefers complete lines and its results are not shortened again by the general tool-output limit. A status block follows the content unless the whole file was returned with nothing to report. A line that cannot fit on its own page is returned in fragments; the status reports the column range and `Next Read` arguments to retrieve the rest without raising the budget. Join fragments of the same line without adding a newline. A partial line remains in the requested `n_lines` range until its ending is returned. Invalid column positions return an error rather than skipping content.

Tail reads return the newest complete lines in the requested range first. If no complete line fits, the result includes forward `Next Read` arguments for the unread range; `column_offset` cannot be combined with a negative `line_offset`. Continuation positions refer to the current file contents, so start a new read if the file changes. If a tail read reports that the file changed during reading, retry against the updated file. UTF-16 LE/BE files up to 10 MiB are checked with strict decoding first. If decoding fails, `Read` returns readable text with malformed sequences replaced by `�`, and every page warns that decoding was lossy and the text may differ from the original. The warning counts toward the character budget; a literal `�` in a valid file does not trigger it. Use `ReadMediaFile` for images or videos.

Expand Down
6 changes: 3 additions & 3 deletions docs/zh/configuration/config-files.md
Original file line number Diff line number Diff line change
Expand Up @@ -451,15 +451,15 @@ disabled = ["WebSearch", "FetchURL", "mcp__github__*"]
| 字段 | 类型 | 默认值 | 说明 |
| --- | --- | --- | --- |
| `default_max_chars` | `integer` | `100000` | 工具调用未指定 `max_chars` 时的字符额度 |
| `max_chars` | `integer` | `500000` | 单次工具调用可申请的最大字符额度 |
| `max_chars` | `integer` | `100000` | 单次工具调用可申请的最大字符额度 |

```toml
[read]
default_max_chars = 100000
max_chars = 500000
max_chars = 100000
```

两个值都必须是正整数。调用中的 `max_chars` 覆盖默认值,但不会超过配置的最大值;结果会说明实际生效的额度。如果配置的默认值超过最大值,默认读取也会按最大值执行。如果希望较大的文档默认就能一次返回,无需 Agent 主动申请更大额度,可以提高 `default_max_chars`。
两个值都必须是正整数。调用中的 `max_chars` 覆盖默认值,但不会超过配置的最大值;结果会说明实际生效的额度。如果配置的默认值超过最大值,默认读取也会按最大值执行。单次调用还会在估算 token 数达到 `max_chars` 的四分之一时停止(每个非 ASCII 字符计 1 个 token,每 4 个 ASCII 字符计 1 个),因此中文等非 ASCII 字符较多的文本每次返回的字符更少。如果希望单次调用返回超过 100000 个字符或约 25000 个 token,需要提高 `max_chars`;如果还希望较大的文档默认就能一次返回,无需 Agent 主动申请更大额度,再同时提高 `default_max_chars`。

## `image`

Expand Down
4 changes: 2 additions & 2 deletions docs/zh/reference/tools.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@
| `Glob` | 自动放行 | 按 glob 模式查找文件 |
| `ReadMediaFile` | 自动放行 | 读取图片或视频文件 |

**`Read`** 接受文件路径(`path`)以及可选的 `line_offset`(起始行号,支持负数从末尾倒数)、`column_offset`(正向读取时,起始行内从 0 开始的位置)、`n_lines`(请求读取的源文件行数)和 `max_chars`(结果的字符上限,包含行号和状态信息)。省略 `n_lines` 时向文件末尾读取。默认上限为 100,000 字符,调用可申请到 500,000 字符;两个值都可通过 [`read` 配置](../configuration/config-files.md#read) 修改。字符数和列偏移按显示文本的 JavaScript 字符串长度计算,列偏移不包含行号前缀:常见字母和汉字各计 1,许多 emoji 计 2。
**`Read`** 接受文件路径(`path`)以及可选的 `line_offset`(起始行号,支持负数从末尾倒数)、`column_offset`(正向读取时,起始行内从 0 开始的位置)、`n_lines`(请求读取的源文件行数)和 `max_chars`(结果的字符上限,包含行号和状态信息)。省略 `n_lines` 时向文件末尾读取。默认上限和调用可申请的最大值都是 100,000 字符,单次调用还会在估算 token 数达到最大值的四分之一(默认 25,000)时停止,因此中文等非 ASCII 字符较多的文本每次返回的字符更少;两个值都可通过 [`read` 配置](../configuration/config-files.md#read) 修改。如果调用指定了范围(带 `n_lines` 或负的 `line_offset`),而 `max_chars` 之内放得下的行仍超过 token 上限,`Read` 会返回错误并建议一个放得下的范围,而不是只返回其中一部分;只被 `max_chars` 截短的范围仍会返回一页内容并附带 `Next Read` 参数。字符数和列偏移按显示文本的 JavaScript 字符串长度计算,列偏移不包含行号前缀:常见字母和汉字各计 1,许多 emoji 计 2。

`Read` 优先返回完整行,结果不会再被通用工具输出限制缩短。如果单独一行也无法在一页中容纳,工具会返回片段,并在状态中说明列范围及 `Next Read` 参数,无需提高额度即可继续读取。拼接同一行的片段时不要额外插入换行。一行只返回部分内容时,仍会计入剩余的 `n_lines` 范围,直到行尾返回为止。非法列偏移会明确报错,不会跳过内容。
`Read` 优先返回完整行,结果不会再被通用工具输出限制缩短。除非一次就返回了整个文件且没有需要说明的情况,否则内容后面会附带状态信息。如果单独一行也无法在一页中容纳,工具会返回片段,并在状态中说明列范围及 `Next Read` 参数,无需提高额度即可继续读取。拼接同一行的片段时不要额外插入换行。一行只返回部分内容时,仍会计入剩余的 `n_lines` 范围,直到行尾返回为止。非法列偏移会明确报错,不会跳过内容。

尾读优先返回请求范围中较新的完整行。如果连一条完整行都无法容纳,结果会给出未读范围的正向 `Next Read` 参数;`column_offset` 不能与负数 `line_offset` 同时使用。续读位置针对文件的当前内容,文件变化后应重新读取。如果尾读提示读取期间文件发生变化,请基于更新后的文件重试。10 MiB 以内的 UTF-16 LE/BE 文件会先尝试严格解码;失败后,`Read` 会将损坏序列替换为 `�` 并返回可读文本,同时在每一页提示发生了有损解码、文本可能与原文不同。告警也计入字符额度;有效文件中原本就有的 `�` 不会触发告警。图片和视频请使用 `ReadMediaFile`。

Expand Down
5 changes: 4 additions & 1 deletion packages/agent-core-v2/src/agent/tools/edit/editTool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,10 @@ export class EditTool implements IEditTool {
return { isError: true, output: result.error };
}
const word = result.count === 1 ? 'occurrence' : 'occurrences';
return { output: `Replaced ${String(result.count)} ${word} in ${args.path}` };
return {
output: `Replaced ${String(result.count)} ${word} in ${args.path}`,
note: '<system>The change is applied; there is no need to Read the file back to check it.</system>',
};
}
}

Expand Down
4 changes: 2 additions & 2 deletions packages/agent-core-v2/src/agent/tools/os/read/read.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ If the user provides a concrete file path to a text file, call Read directly. Do

When you need several files, prefer to read them in parallel: emit multiple `Read` calls in a single response instead of reading one file per turn.

- Output is `<line-number>\t<content>` per line, followed by a `<system>` status block that is not part of the file.
- Results are bounded by `max_chars`: ${DEFAULT_MAX_CHARS} by default, up to ${MAX_CHARS}. When the task requires the full text of a large file, request a larger `max_chars` in the first call.
- Output is `<line-number>\t<content>` per line. A `<system>` status block may follow; it is not part of the file.
- Results are bounded by `max_chars`: ${DEFAULT_MAX_CHARS} by default, up to ${MAX_CHARS}.
- If the status block reports an incomplete range, continue with its `Next Read` arguments exactly. Do not answer from a partial page when the task requires the remaining content.
- After a successful `Edit`/`Write`, do not re-read solely to prove the write landed.
2 changes: 1 addition & 1 deletion packages/agent-core-v2/src/agent/tools/os/read/read.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { createDecorator } from '#/_base/di/instantiation';
import { type AgentTool } from '#/tool/toolContract';

export const DEFAULT_MAX_CHARS = 100_000;
export const DEFAULT_MAX_CHARS_LIMIT = 500_000;
export const DEFAULT_MAX_CHARS_LIMIT = 100_000;

export const TRANSCODE_MAX_BYTES: number = 10 * 1024 * 1024;

Expand Down
Loading
Loading