Skip to content
Open
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
2 changes: 2 additions & 0 deletions packages/core/src/tool/plugin/read.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ const LocationInput = Schema.Struct({
path: Schema.String.annotate({ description: "File or directory to read" }),
offset: ReadToolFileSystem.PageInput.fields.offset.annotate({
description: "The line or directory entry to start reading from (1-based)",
message:
"The offset must be a non-negative integer. Line and entry numbers are 1-based, so prefer omitting the offset or using 1.",
}),
limit: ReadToolFileSystem.PageInput.fields.limit.annotate({
description: "The maximum number of lines or directory entries to read (defaults to 2000)",
Expand Down
20 changes: 19 additions & 1 deletion packages/core/test/tool-read.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,25 @@ describe("ReadTool", () => {
page: { offset: undefined, limit: undefined },
},
])
expect(listCalls).toEqual([])
}),
)

it.effect("surfaces 1-based guidance when the model hallucinates a negative offset", () =>
Effect.gen(function* () {
const registry = yield* Tool.Service
const execution = yield* executeTool(registry, {
sessionID,
...toolIdentity,
call: {
type: "tool-call",
id: "call-read-negative-offset",
name: "read",
input: { path: "README.md", offset: -1 },
},
})
expect(execution.status).toBe("error")
if (execution.status !== "error") return
expect(JSON.stringify(execution.error)).toContain("1-based")
}),
)

Expand Down
Loading