Prerequisites
Background / Description
Edit and Write record the change they made as a unified diff in the tool result's metadata["diff"], and the TUI turns that diff into the +added -removed counter shown on a tool row and on a tool group (tui/_messages.py:384 and tui/_messages.py:441).
_diff_stats (tui/_messages.py:298) excludes the diff's file headers by prefix-testing every line:
if line.startswith("+") and not line.startswith("+++"):
insertions += 1
elif line.startswith("-") and not line.startswith("---"):
deletions += 1
But difflib.unified_diff — which is what both tools call (_edit.py:405, _write.py likewise) — writes the --- a/<path> / +++ b/<path> pair as its first two lines only. Any changed line whose own text starts with the marker collides with that test and silently disappears from the count:
- removing a Markdown or YAML
--- rule emits ----, which is dropped;
- removing a line that is itself
-- something (a shell or SQL comment, a diff printed inside a document) emits --- something, which is dropped;
- adding a C/JS line such as
++counter; emits +++counter;, which is dropped.
So an edit whose whole change is one --- line becoming ++counter; — routine when an agent touches front matter, a document separator, or a counter — is reported as +0 -0. The group summary is worse: it adds the per-call counts and then guards on if added or removed: (tui/_messages.py:449), so when every changed line is swallowed it drops the +N -M section entirely, as if the group had made no changes at all.
Content lines are prefixed with a space, and a hunk header starts with @, so they were never the reason for the exclusion. The only lines that need excluding are the leading pair.
This also disagrees with how the same quantity is produced elsewhere in the repo: app/_service/_workspace.py:561 takes insertions and deletions from git diff --shortstat, i.e. from the tool that generated the diff, rather than from a prefix heuristic applied afterwards.
I have a fix ready: treat only the leading --- / +++ pair as headers and count every other +/- line. Two tests, one pinning the plain case so the header pair is still excluded once.
Error Messages
No exception is raised; the reported behavior is a wrong count. Reproduction output on main:
diff the Edit tool records:
--- a/README.md
+++ b/README.md
@@ -1 +1 @@
----
+++counter;
_diff_stats -> (0, 0) expected (1, 1)
real Edit metadata diff:
--- a/<tmp>/README.md
+++ b/<tmp>/README.md
@@ -1 +1 @@
----
+++counter;
_diff_stats -> (0, 0)
Steps to Reproduce
No network access and no API keys required.
- Code:
import asyncio
import difflib
import os
import tempfile
from agentscope.tool import Edit
from agentscope.tui._messages import _diff_stats
async def main() -> None:
path = os.path.join(tempfile.mkdtemp(), "README.md")
# What the producer emits, and what the counter makes of it.
demo = "".join(
difflib.unified_diff(
["---\n"],
["++counter;\n"],
fromfile="a/README.md",
tofile="b/README.md",
n=3,
),
)
print("diff the Edit tool records:")
print(demo)
print("_diff_stats ->", _diff_stats(demo), " expected (1, 1)\n")
with open(path, "w", encoding="utf-8") as f:
f.write("---\n")
chunk = await Edit()(
file_path=path,
old_string="---",
new_string="++counter;",
)
print("real Edit metadata diff:")
print(chunk.metadata["diff"])
print("_diff_stats ->", _diff_stats(chunk.metadata["diff"]))
asyncio.run(main())
- Run:
python repro.py on main at 2c885b5
- See: both counts are
(0, 0) although the diff contains exactly one added and one removed line.
Environment
- AgentScope Version: 2.0.8 (
main @ 2c885b5)
- Python Version: 3.12.12 (
agentscope[tui] installed)
- OS: macOS 15.6 (arm64) — pure string handling, reproduces identically on Linux and Windows
Prerequisites
Background / Description
EditandWriterecord the change they made as a unified diff in the tool result'smetadata["diff"], and the TUI turns that diff into the+added -removedcounter shown on a tool row and on a tool group (tui/_messages.py:384andtui/_messages.py:441)._diff_stats(tui/_messages.py:298) excludes the diff's file headers by prefix-testing every line:But
difflib.unified_diff— which is what both tools call (_edit.py:405,_write.pylikewise) — writes the--- a/<path>/+++ b/<path>pair as its first two lines only. Any changed line whose own text starts with the marker collides with that test and silently disappears from the count:---rule emits----, which is dropped;-- something(a shell or SQL comment, a diff printed inside a document) emits--- something, which is dropped;++counter;emits+++counter;, which is dropped.So an edit whose whole change is one
---line becoming++counter;— routine when an agent touches front matter, a document separator, or a counter — is reported as+0 -0. The group summary is worse: it adds the per-call counts and then guards onif added or removed:(tui/_messages.py:449), so when every changed line is swallowed it drops the+N -Msection entirely, as if the group had made no changes at all.Content lines are prefixed with a space, and a hunk header starts with
@, so they were never the reason for the exclusion. The only lines that need excluding are the leading pair.This also disagrees with how the same quantity is produced elsewhere in the repo:
app/_service/_workspace.py:561takes insertions and deletions fromgit diff --shortstat, i.e. from the tool that generated the diff, rather than from a prefix heuristic applied afterwards.I have a fix ready: treat only the leading
---/+++pair as headers and count every other+/-line. Two tests, one pinning the plain case so the header pair is still excluded once.Error Messages
No exception is raised; the reported behavior is a wrong count. Reproduction output on
main:Steps to Reproduce
No network access and no API keys required.
python repro.pyonmainat2c885b5(0, 0)although the diff contains exactly one added and one removed line.Environment
main@2c885b5)agentscope[tui]installed)