pi-readseek 0.6.5 → 0.6.6

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": "pi-readseek",
3
- "version": "0.6.5",
3
+ "version": "0.6.6",
4
4
  "description": "Pi extension for readseek-backed hash-anchored read/edit/grep, structural code maps, structural search, and file exploration",
5
5
  "type": "module",
6
6
  "exports": {
@@ -39,7 +39,7 @@
39
39
  "node": ">=20.0.0"
40
40
  },
41
41
  "dependencies": {
42
- "@jarkkojs/readseek": "^0.6.5",
42
+ "@jarkkojs/readseek": "^0.6.6",
43
43
  "diff": "^8.0.3",
44
44
  "xxhash-wasm": "^1.1.0"
45
45
  },
package/src/read.ts CHANGED
@@ -66,7 +66,7 @@ function hasReadAnchors(result: AgentToolResult<any>): boolean {
66
66
  return Array.isArray(lines) && lines.length > 0;
67
67
  }
68
68
 
69
- function formatImageAnalysis(detection: ReadSeekDetection): string | undefined {
69
+ function formatImageAnalysis(detection: ReadSeekDetection, mode: "ocr" | "caption" | "objects"): string | undefined {
70
70
  if (detection.kind !== "image") return undefined;
71
71
  const sections: string[] = [];
72
72
  const ocr = detection.ocr?.trim();
@@ -77,7 +77,10 @@ function formatImageAnalysis(detection: ReadSeekDetection): string | undefined {
77
77
  const lines = detection.objects.map((object) => `- ${object.label} [${object.bbox.join(", ")}]`);
78
78
  sections.push(`Detected objects:\n${lines.join("\n")}`);
79
79
  }
80
- return sections.length > 0 ? sections.join("\n\n") : undefined;
80
+ if (sections.length > 0) return sections.join("\n\n");
81
+ if (mode === "ocr") return "No OCR text detected in image.";
82
+ if (mode === "objects") return "No objects detected in image.";
83
+ return "Image caption returned no text.";
81
84
  }
82
85
 
83
86
  function formatPdfAnalysis(pdf: ReadSeekPdfOutput): string {
@@ -246,7 +249,7 @@ export async function executeRead(opts: ExecuteReadOptions): Promise<AgentToolRe
246
249
  });
247
250
  }
248
251
  const analysis = await readSeekImage(absolutePath, [p.image], { signal });
249
- const imageAnalysis = formatImageAnalysis(analysis);
252
+ const imageAnalysis = formatImageAnalysis(analysis, p.image);
250
253
  if (imageAnalysis) {
251
254
  return succeed({
252
255
  content: [{ type: "text" as const, text: imageAnalysis }],
@@ -480,6 +480,29 @@ async function runReadSeek(args: string[], options: RunReadSeekOptions = {}): Pr
480
480
  return JSON.parse(stdout) as unknown;
481
481
  }
482
482
 
483
+ let visionInvocationTail = Promise.resolve();
484
+
485
+ /**
486
+ * Serialize local vision-model processes. Concurrent processes each consume all
487
+ * available CPU cores, which makes every invocation exceed its own timeout.
488
+ */
489
+ async function runReadSeekVision(args: string[], options: RunReadSeekOptions = {}): Promise<unknown> {
490
+ let release!: () => void;
491
+ const gate = new Promise<void>((resolve) => {
492
+ release = resolve;
493
+ });
494
+ const predecessor = visionInvocationTail;
495
+ visionInvocationTail = predecessor.then(() => gate);
496
+
497
+ await predecessor;
498
+ try {
499
+ options.signal?.throwIfAborted();
500
+ return await runReadSeek(args, options);
501
+ } finally {
502
+ release();
503
+ }
504
+ }
505
+
483
506
  function requireNumber(value: unknown, field: string): number {
484
507
  if (typeof value !== "number" || !Number.isSafeInteger(value)) throw new Error(`invalid readseek ${field}: expected safe integer`);
485
508
  return value;
@@ -830,7 +853,7 @@ export async function readSeekImage(
830
853
  ): Promise<ReadSeekDetection> {
831
854
  const results = await Promise.allSettled(
832
855
  modes.map(async (mode) =>
833
- parseDetectOutput(await runReadSeek(["read", "--image", mode, filePath], { signal: options.signal })),
856
+ parseDetectOutput(await runReadSeekVision(["read", "--image", mode, filePath], { signal: options.signal })),
834
857
  ),
835
858
  );
836
859
 
@@ -903,7 +926,8 @@ export async function readSeekPdf(
903
926
  mode: "none" | ReadSeekImageMode,
904
927
  options: { signal?: AbortSignal } = {},
905
928
  ): Promise<ReadSeekPdfOutput> {
906
- return parsePdfOutput(await runReadSeek(["read", "--image", mode, filePath], { signal: options.signal }));
929
+ const run = mode === "none" ? runReadSeek : runReadSeekVision;
930
+ return parsePdfOutput(await run(["read", "--image", mode, filePath], { signal: options.signal }));
907
931
  }
908
932
 
909
933
  // --- Rename ---