diff --git a/packages/core/src/tool/read-filesystem.ts b/packages/core/src/tool/read-filesystem.ts index 9eb523d20a1..5cccbaed7f2 100644 --- a/packages/core/src/tool/read-filesystem.ts +++ b/packages/core/src/tool/read-filesystem.ts @@ -361,12 +361,8 @@ const textOffset = (tree: TextNode, newline: number) => { if (!child) return tree.summary.bytes node = child } - for (const [index, byte] of node.bytes.entries()) { - if (byte !== 10) continue - remaining-- - if (remaining === 0) return offset + index + 1 - } - return tree.summary.bytes + const end = nthNewline(node.bytes, remaining) + return end === undefined ? tree.summary.bytes : offset + end } const nthNewline = (bytes: Uint8Array, count: number) => { diff --git a/packages/core/test/tool-read-filesystem.test.ts b/packages/core/test/tool-read-filesystem.test.ts index 2d9955532f1..41c673599e1 100644 --- a/packages/core/test/tool-read-filesystem.test.ts +++ b/packages/core/test/tool-read-filesystem.test.ts @@ -257,6 +257,21 @@ describe("ReadToolFileSystem", () => { }), ) + it.effect("reads after a newline at the first chunk boundary", () => + Effect.gen(function* () { + const { environment, files, directory } = yield* fixture + const file = path.join(directory, "boundary.txt") + yield* files.writeFileString(file, `${"a".repeat(256 * 1024 - 1)}\nsecond\n`) + + const result = yield* ReadToolFileSystem.read(environment, absolute(file), "boundary.txt", { + offset: 2, + limit: 1, + }) + + expect(result).toMatchObject({ type: "text-page", content: "second", offset: 2, truncated: false }) + }), + ) + it.effect("preserves the media ingestion limit message", () => Effect.gen(function* () { const { environment, files, directory } = yield* fixture