diff --git a/packages/coding-agent/src/tools/read.ts b/packages/coding-agent/src/tools/read.ts index 454aa828d..1a9140064 100644 --- a/packages/coding-agent/src/tools/read.ts +++ b/packages/coding-agent/src/tools/read.ts @@ -3244,6 +3244,7 @@ export class ReadTool implements AgentTool { if (!rawSelector && artifact.size > MAX_ARTIFACT_RAW_INLINE_BYTES) { outputText += `\n\n[${this.#formatArtifactWorkflowNotice(artifact, artifactUrl)}]`; } + if (reachedEof) details.totalLines = totalFileLines; if (displayContent) details.displayContent = displayContent; if (truncationInfo) details.truncation = truncationInfo.result; const resultBuilder = toolResult(details) diff --git a/packages/coding-agent/test/tools/read-artifact-large.test.ts b/packages/coding-agent/test/tools/read-artifact-large.test.ts index 46831a30f..389bebc2b 100644 --- a/packages/coding-agent/test/tools/read-artifact-large.test.ts +++ b/packages/coding-agent/test/tools/read-artifact-large.test.ts @@ -104,6 +104,12 @@ describe("read tool large artifact handling", () => { expect(output).not.toContain("line-032"); }); + it("records the source line count for an open-ended artifact range that reaches EOF", async () => { + const result = await tool.execute("call-raw-tail", { path: "artifact://0:raw:301-" }); + + expect(result.details?.totalLines).toBe(400); + }); + it("shortens artifact paths under the user's home dir instead of leaking the absolute path", async () => { const homeSpy = spyOn(os, "homedir").mockReturnValue(testDir); try {