@lazyingart/agintiflow 0.20.135 → 0.20.137

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lazyingart/agintiflow",
3
- "version": "0.20.135",
3
+ "version": "0.20.137",
4
4
  "type": "module",
5
5
  "description": "AgInTiFlow is a project-aware agent workspace for hybrid wet-dry R&D, hardware-aware intelligence, software automation, and industrial workflows.",
6
6
  "license": "Apache-2.0",
@@ -671,6 +671,30 @@ try {
671
671
  assert(sanitizedSmallRead.content === longSmallFile, "small read_file result did not keep full content for the model");
672
672
  assert(sanitizedSmallRead.contentTruncated === false, "small read_file result should not be marked truncated");
673
673
  assert(!("contentPreview" in sanitizedSmallRead), "small read_file result should not replace full content with preview");
674
+ const limitedReadResult = await executeWorkspaceTool(
675
+ "read_file",
676
+ { path: "small-read-smoke.md", startLine: 2, lineLimit: 3 },
677
+ {
678
+ commandCwd: workspace,
679
+ allowFileTools: true,
680
+ }
681
+ );
682
+ assert(limitedReadResult.content === "line 001\nline 002\nline 003", "read_file lineLimit did not return the requested line slice");
683
+ assert(limitedReadResult.contentTruncatedByLines === true, "read_file lineLimit should report remaining lines");
684
+ const largeReadLines = Array.from({ length: 30000 }, (_, index) => `large line ${String(index + 1).padStart(5, "0")}`).join("\n");
685
+ await fs.writeFile(path.join(workspace, "large-read-smoke.md"), largeReadLines, "utf8");
686
+ const largeLimitedReadResult = await executeWorkspaceTool(
687
+ "read_file",
688
+ { path: "large-read-smoke.md", startLine: 100, lineLimit: 2 },
689
+ {
690
+ commandCwd: workspace,
691
+ allowFileTools: true,
692
+ }
693
+ );
694
+ assert(
695
+ largeLimitedReadResult.content === "large line 00100\nlarge line 00101",
696
+ "read_file lineLimit should work on larger text files"
697
+ );
674
698
  const inspected = await executeWorkspaceTool(
675
699
  "inspect_project",
676
700
  { path: ".", maxDepth: 4, limit: 200 },
@@ -1153,6 +1153,9 @@ export async function requestNextStep(client, config, messages) {
1153
1153
  type: "object",
1154
1154
  properties: {
1155
1155
  path: { type: "string", description: "Workspace-relative file path." },
1156
+ startLine: { type: "integer", description: "Optional 1-based first line to read." },
1157
+ lineLimit: { type: "integer", description: "Optional maximum number of lines to read; use this for large source files." },
1158
+ limit: { type: "integer", description: "Alias for lineLimit for compatibility with older prompts." },
1156
1159
  },
1157
1160
  required: ["path"],
1158
1161
  additionalProperties: false,
@@ -7,6 +7,7 @@ export const WORKSPACE_TOOL_NAMES = ["inspect_project", "list_files", "read_file
7
7
  export const WORKSPACE_WRITE_TOOL_NAMES = ["write_file", "apply_patch"];
8
8
 
9
9
  const MAX_READ_BYTES = 220_000;
10
+ const MAX_LINE_LIMIT_READ_BYTES = 5_000_000;
10
11
  const MAX_WRITE_BYTES = 220_000;
11
12
  const MAX_PATCH_BYTES = 260_000;
12
13
  const MAX_LIST_ENTRIES = 360;
@@ -390,10 +391,14 @@ async function listFiles(config, args) {
390
391
  };
391
392
  }
392
393
 
393
- async function readTextFile(target) {
394
+ async function readTextFile(target, { allowLargeLineLimited = false } = {}) {
394
395
  const stat = await fs.stat(target.absolutePath);
395
396
  if (!stat.isFile()) throw new Error(`Path is not a file: ${target.relativePath}`);
396
- if (stat.size > MAX_READ_BYTES) throw new Error(`File is too large to read safely: ${target.relativePath}`);
397
+ if (stat.size > MAX_READ_BYTES) {
398
+ if (!allowLargeLineLimited || stat.size > MAX_LINE_LIMIT_READ_BYTES) {
399
+ throw new Error(`File is too large to read safely: ${target.relativePath}`);
400
+ }
401
+ }
397
402
 
398
403
  const buffer = await fs.readFile(target.absolutePath);
399
404
  if (buffer.includes(0)) throw new Error(`Binary files are not readable through this tool: ${target.relativePath}`);
@@ -406,14 +411,24 @@ async function readTextFile(target) {
406
411
 
407
412
  async function readFile(config, args) {
408
413
  const target = resolveWorkspacePath(config, args.path);
409
- const { stat, content, hash } = await readTextFile(target);
414
+ const requestedLineLimit = Number(args.lineLimit || args.limit || 0);
415
+ const lineLimit = Number.isFinite(requestedLineLimit) && requestedLineLimit > 0 ? Math.min(requestedLineLimit, 1000) : 0;
416
+ const { stat, content, hash } = await readTextFile(target, { allowLargeLineLimited: lineLimit > 0 });
417
+ const lines = content.split(/\r?\n/);
418
+ const startLine = Math.min(Math.max(Number(args.startLine) || 1, 1), Math.max(lines.length, 1));
419
+ const selectedLines = lineLimit > 0 ? lines.slice(startLine - 1, startLine - 1 + lineLimit) : lines;
420
+ const selectedContent = selectedLines.join("\n");
410
421
  return {
411
422
  ok: true,
412
423
  toolName: "read_file",
413
424
  path: target.relativePath,
414
425
  bytes: stat.size,
415
426
  sha256: hash,
416
- content: redactSensitiveText(content),
427
+ content: redactSensitiveText(selectedContent),
428
+ startLine,
429
+ lineLimit: lineLimit || null,
430
+ lineCount: lines.length,
431
+ contentTruncatedByLines: lineLimit > 0 && startLine - 1 + lineLimit < lines.length,
417
432
  };
418
433
  }
419
434