Skip to content

Commit 25a5cb3

Browse files
committed
fix(memory): default non-finite qmd read windows
1 parent f3cfd75 commit 25a5cb3

2 files changed

Lines changed: 42 additions & 6 deletions

File tree

extensions/memory-core/src/memory/qmd-manager.test.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4401,6 +4401,35 @@ describe("QmdMemoryManager", () => {
44014401
readFileSpy.mockRestore();
44024402
});
44034403

4404+
it("defaults non-finite partial read line options before streaming canonical memory files", async () => {
4405+
const readFileSpy = vi.spyOn(fs, "readFile");
4406+
const relPath = path.join("memory", "non-finite-window.md");
4407+
await fs.mkdir(path.join(workspaceDir, "memory"), { recursive: true });
4408+
await fs.writeFile(
4409+
path.join(workspaceDir, relPath),
4410+
["line-1", "line-2", "line-3"].join("\n"),
4411+
"utf-8",
4412+
);
4413+
4414+
const { manager } = await createManager();
4415+
4416+
const result = await manager.readFile({
4417+
relPath,
4418+
from: Number.NaN,
4419+
lines: Number.POSITIVE_INFINITY,
4420+
});
4421+
expect(result).toEqual({
4422+
path: relPath,
4423+
text: "line-1\nline-2\nline-3",
4424+
from: 1,
4425+
lines: 3,
4426+
});
4427+
expect(readFileSpy).not.toHaveBeenCalled();
4428+
4429+
await manager.close();
4430+
readFileSpy.mockRestore();
4431+
});
4432+
44044433
it("returns a bounded default excerpt for qmd memory reads without explicit lines", async () => {
44054434
const relPath = path.join("memory", "default-window.md");
44064435
await fs.mkdir(path.join(workspaceDir, "memory"), { recursive: true });

extensions/memory-core/src/memory/qmd-manager.ts

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,12 @@ type McporterState = {
126126
daemonStart: Promise<void> | null;
127127
};
128128

129+
function normalizePositiveInteger(value: number | undefined, fallback: number): number {
130+
return typeof value === "number" && Number.isFinite(value)
131+
? Math.max(1, Math.floor(value))
132+
: fallback;
133+
}
134+
129135
type QmdEmbedQueueState = {
130136
tail: Promise<void>;
131137
};
@@ -1333,18 +1339,19 @@ export class QmdMemoryManager implements MemorySearchManager {
13331339
}
13341340
const contextLimits = this.contextLimits;
13351341
if (params.from !== undefined || params.lines !== undefined) {
1336-
const requestedCount = Math.max(
1337-
1,
1342+
const startLine = normalizePositiveInteger(params.from, 1);
1343+
const requestedCount = normalizePositiveInteger(
13381344
params.lines ?? contextLimits?.memoryGetDefaultLines ?? DEFAULT_MEMORY_READ_LINES,
1345+
DEFAULT_MEMORY_READ_LINES,
13391346
);
1340-
const partial = await this.readPartialText(absPath, params.from, requestedCount);
1347+
const partial = await this.readPartialText(absPath, startLine, requestedCount);
13411348
if (partial.missing) {
13421349
return { text: "", path: relPath };
13431350
}
13441351
return buildMemoryReadResultFromSlice({
13451352
selectedLines: partial.selectedLines,
13461353
relPath,
1347-
startLine: Math.max(1, params.from ?? 1),
1354+
startLine,
13481355
moreSourceLinesRemain: partial.moreSourceLinesRemain,
13491356
maxChars: contextLimits?.memoryGetMaxChars,
13501357
suggestReadFallback: isDefaultMemoryPath(relPath),
@@ -2205,8 +2212,8 @@ export class QmdMemoryManager implements MemorySearchManager {
22052212
): Promise<
22062213
{ missing: true } | { missing: false; selectedLines: string[]; moreSourceLinesRemain: boolean }
22072214
> {
2208-
const start = Math.max(1, from ?? 1);
2209-
const count = Math.max(1, lines ?? Number.POSITIVE_INFINITY);
2215+
const start = normalizePositiveInteger(from, 1);
2216+
const count = normalizePositiveInteger(lines, Number.MAX_SAFE_INTEGER);
22102217
let handle;
22112218
try {
22122219
handle = await fs.open(absPath);

0 commit comments

Comments
 (0)