Skip to content

Commit 3617539

Browse files
committed
fix: validate memory get ranges
1 parent 56a5d7e commit 3617539

5 files changed

Lines changed: 23 additions & 6 deletions

File tree

extensions/memory-core/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,8 @@ const MemoryGetSchema = {
7474
type: "object",
7575
properties: {
7676
path: { type: "string" },
77-
from: { type: "number" },
78-
lines: { type: "number" },
77+
from: { type: "integer", minimum: 1 },
78+
lines: { type: "integer", minimum: 1 },
7979
corpus: { type: "string", enum: ["memory", "wiki", "all"] },
8080
},
8181
required: ["path"],

extensions/memory-core/src/tools.citations.test.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,21 @@ describe("memory tools", () => {
207207
expect(getMemorySearchManagerMockCalls()).toBe(0);
208208
});
209209

210+
it("rejects fractional memory_get ranges before reading files", async () => {
211+
setMemoryBackend("builtin");
212+
const tool = createMemoryGetToolOrThrow();
213+
214+
await expect(
215+
tool.execute("call_fractional_range", {
216+
path: "memory/2026-02-19.md",
217+
from: 1.5,
218+
lines: 2,
219+
}),
220+
).rejects.toThrow("from must be a positive integer");
221+
expect(getReadAgentMemoryFileMockCalls()).toBe(0);
222+
expect(getMemorySearchManagerMockCalls()).toBe(0);
223+
});
224+
210225
it("returns truncation metadata and a continuation notice for partial memory_get results", async () => {
211226
setMemoryBackend("builtin");
212227
setMemoryReadFileImpl(async (params: MemoryReadParams) => ({

extensions/memory-core/src/tools.shared.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ export const MemorySearchSchema = Type.Object({
3737

3838
export const MemoryGetSchema = Type.Object({
3939
path: Type.String(),
40-
from: Type.Optional(Type.Number()),
41-
lines: Type.Optional(Type.Number()),
40+
from: Type.Optional(Type.Integer()),
41+
lines: Type.Optional(Type.Integer()),
4242
corpus: Type.Optional(stringEnum(["memory", "wiki", "all"])),
4343
});
4444

extensions/memory-core/src/tools.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
asToolParamsRecord,
55
jsonResult,
66
readNumberParam,
7+
readPositiveIntegerParam,
78
readStringParam,
89
type MemoryCorpusSearchResult,
910
type OpenClawConfig,
@@ -443,8 +444,8 @@ export function createMemoryGetTool(options: {
443444
async (_toolCallId, params) => {
444445
const rawParams = asToolParamsRecord(params);
445446
const relPath = readStringParam(rawParams, "path", { required: true });
446-
const from = readNumberParam(rawParams, "from", { integer: true });
447-
const lines = readNumberParam(rawParams, "lines", { integer: true });
447+
const from = readPositiveIntegerParam(rawParams, "from");
448+
const lines = readPositiveIntegerParam(rawParams, "lines");
448449
const requestedCorpus = readStringParam(rawParams, "corpus") as
449450
| "memory"
450451
| "wiki"

src/plugin-sdk/memory-core-host-runtime-core.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ export {
88
asToolParamsRecord,
99
jsonResult,
1010
readNumberParam,
11+
readPositiveIntegerParam,
1112
readStringParam,
1213
type AnyAgentTool,
1314
} from "../agents/tools/common.js";

0 commit comments

Comments
 (0)