agentscope-ai / agentscope-ai/agentscope-java

[Bug]: read_file line pagination can return unbounded output for a single-line file

オープン
#2,951 コメント 2 件 リアクション 0 件 担当者 0 名 GitHub で見る
area/harness bug
主要言語
Java
スター
5.6k
フォーク
1.3k
平均マージ
4日 12時間
マージ済み PR(30日)
77

説明

**Describe the bug**

The Harness `read_file` tool paginates by line count through its `offset` and
`limit` parameters, but it does not impose a character or byte limit on the
returned content.

For a file containing one very large line, such as a multi-megabyte JSON file,
`read_file(path, offset=0, limit=1)` returns the entire line. Therefore, even a
small line limit can produce an unbounded tool result and exceed the model
context window.

This is particularly problematic because `read_file` is included in
`ToolResultEvictionConfig.DEFAULT_EXCLUDED_TOOLS`. The oversized result is
therefore not handled by `ToolResultEvictionMiddleware` and is passed directly
to the next model call.

Removing `read_file` from the exclusion set is not a complete workaround:
when the agent reads an evicted artifact and that read is itself oversized,
the result can be evicted into another artifact. The agent then receives
another placeholder instead of a reliably bounded chunk.

The ranged-read optimization merged in #2402 reduces memory usage by reading
only the requested lines, but a single requested line can still be arbitrarily
large.

**To Reproduce**

1. Create a workspace file containing a multi-megabyte single line:

```bash
{
printf '{"payload":"'
head -c 5000000 /dev/zero | tr '\0' 'a'
printf '"}'
} > large-single-line.json
```

2. Build a `HarnessAgent` with its default filesystem tools and default
`ToolResultEvictionConfig`.

3. Have the agent execute:

```text
read_file(
path="large-single-line.json",
offset=0,
limit=1
)
```

4. Observe that the tool result contains the complete multi-megabyte line,
despite `limit=1`.

5. The result bypasses tool-result eviction because `read_file` is excluded,
and the following model request can fail with a context-length error.

The same behavior can be reproduced directly through
`FilesystemTool.readFile(...)` and an `AbstractFilesystem` implementation.

**Expected behavior**

`read_file` should have a hard output-size boundary independent of line count.

A possible backward-compatible design would be:

- add an optional `max_chars` or `max_bytes` parameter;
- enforce a conservative default maximum;
- stop reading when either the line limit or size limit is reached;
- return explicit truncation metadata or guidance;
- provide a byte/character continuation offset for reading the remainder;
- preserve UTF-8 character boundaries;
- handle a single line larger than the limit without returning the whole line.

For example, the result could indicate:

```text
[Content truncated: returned bytes 0-65535.
Continue with byte_offset=65536.]
```

This would allow `read_file` to remain excluded from tool-result eviction while
still guaranteeing bounded model input.

`grep_files`, `glob_files`, and similar discovery tools already received
bounded-result handling on `main`; `read_file` needs an equivalent boundary
that also works for files without newline characters.

**Error messages**

There is no error at the tool layer. The oversized result is returned
successfully.

The subsequent model call may fail with an error similar to:

```text
context length exceeded
```

or emergency compaction may fail because the oversized tool result has already
entered the reasoning context.

**Environment (please complete the following information):**

- AgentScope-Java Version: 2.0.1; current `main` also appears affected
- Java Version: 21
- OS: Linux

**Additional context**

Related upstream work:

- #2319 fixed tool-result eviction for the immediate reasoning input and
persisted history.
- #2402 changed ranged file reads to stream requested lines, but did not add a
character/byte output limit.
- #2134 notes that recall tools may need exclusion from tool-result eviction to
avoid immediately evicting recalled content again.

This issue is specifically about making filesystem reads intrinsically bounded,
rather than relying on tool-result eviction to handle an already oversized
`read_file` result.

コントリビューションガイド

コントリビューションガイドを開く

評価

この issue はまだ評価されていません。

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。