pi-readseek 0.12.4 → 0.12.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/README.md +4 -0
- package/dist/index.ts +45 -15
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -27,6 +27,10 @@ attachments without a separate extraction call. Reading never runs local inferen
|
|
|
27
27
|
captioning, detection, and OCR require their explicit tools. Legacy tool names and
|
|
28
28
|
selectable inspection facets are removed.
|
|
29
29
|
|
|
30
|
+
Image attachments share a 32 MiB base64-data budget per tool result. Images that
|
|
31
|
+
would exceed the remaining budget are omitted with a notice and their file path;
|
|
32
|
+
smaller images later in the result can still be attached.
|
|
33
|
+
|
|
30
34
|
The four `show` tools display readable summaries and grouped details rather than
|
|
31
35
|
JSON dumps. Expand with Ctrl+O to reveal content; long lines wrap on resize.
|
|
32
36
|
Source anchors, selected document nodes, asset paths, and continuation notices
|
package/dist/index.ts
CHANGED
|
@@ -5374,7 +5374,9 @@ function registerDefTool(pi, options = {}) {
|
|
|
5374
5374
|
// src/access.ts
|
|
5375
5375
|
import { Text as Text7, wrapTextWithAnsi as wrapTextWithAnsi2 } from "@earendil-works/pi-tui";
|
|
5376
5376
|
import { Type as Type11 } from "@sinclair/typebox";
|
|
5377
|
-
import {
|
|
5377
|
+
import { createReadStream } from "node:fs";
|
|
5378
|
+
import { stat } from "node:fs/promises";
|
|
5379
|
+
var MAX_IMAGE_ATTACHMENT_BYTES = 32 * 1024 * 1024;
|
|
5378
5380
|
var operations = {
|
|
5379
5381
|
show: readSeekShow,
|
|
5380
5382
|
tree: readSeekTree,
|
|
@@ -5386,22 +5388,25 @@ var operations = {
|
|
|
5386
5388
|
objects: readSeekObjects,
|
|
5387
5389
|
ocr: readSeekOcr
|
|
5388
5390
|
};
|
|
5389
|
-
function resolveNonShowSummary(
|
|
5390
|
-
if (
|
|
5391
|
-
|
|
5391
|
+
function resolveNonShowSummary(value) {
|
|
5392
|
+
if (!value)
|
|
5393
|
+
return "complete";
|
|
5394
|
+
if (value.tool === "syntax") {
|
|
5395
|
+
const errorCount = value.envelope.errorCount + value.envelope.missingCount;
|
|
5392
5396
|
return errorCount === 0 ? "clean" : `${errorCount} syntax error${errorCount === 1 ? "" : "s"}`;
|
|
5393
5397
|
}
|
|
5394
|
-
if (tool === "check") {
|
|
5395
|
-
const violations =
|
|
5398
|
+
if (value.tool === "check") {
|
|
5399
|
+
const violations = value.envelope.violation_count;
|
|
5396
5400
|
return violations === 0 ? "clean" : `${violations} rule violation${violations === 1 ? "" : "s"}`;
|
|
5397
5401
|
}
|
|
5398
|
-
if (tool === "objects") {
|
|
5399
|
-
const
|
|
5402
|
+
if (value.tool === "objects") {
|
|
5403
|
+
const envelope = value.envelope;
|
|
5404
|
+
const objects = "vision" in envelope ? envelope.vision.reduce((count, vision) => count + (vision.objects?.length ?? 0), 0) : ("objects" in envelope.content) ? envelope.content.objects?.length ?? 0 : 0;
|
|
5400
5405
|
return `${objects} object${objects === 1 ? "" : "s"}`;
|
|
5401
5406
|
}
|
|
5402
|
-
if (tool === "caption")
|
|
5407
|
+
if (value.tool === "caption")
|
|
5403
5408
|
return "caption generated";
|
|
5404
|
-
if (tool === "ocr")
|
|
5409
|
+
if (value.tool === "ocr")
|
|
5405
5410
|
return "text recognized";
|
|
5406
5411
|
return "complete";
|
|
5407
5412
|
}
|
|
@@ -5492,13 +5497,38 @@ async function executeAccess(opts) {
|
|
|
5492
5497
|
{ type: "text", text: presentation ? formatShowResult(presentation) : JSON.stringify(envelope) }
|
|
5493
5498
|
];
|
|
5494
5499
|
if (opts.tool === "show" || opts.tool === "assets") {
|
|
5500
|
+
let remainingImageBytes = MAX_IMAGE_ATTACHMENT_BYTES;
|
|
5495
5501
|
for (const [imagePath, mimeType] of imagePaths(envelope)) {
|
|
5502
|
+
opts.signal?.throwIfAborted();
|
|
5496
5503
|
if (opts.imageMode === "off")
|
|
5497
5504
|
content.push({ type: "text", text: `Image available at ${imagePath}; image attachments are disabled by readseek.imageMode.` });
|
|
5498
|
-
else if (opts.modelSupportsImages)
|
|
5499
|
-
content.push({ type: "image", data: (await readFile2(imagePath)).toString("base64"), mimeType });
|
|
5500
|
-
else
|
|
5505
|
+
else if (!opts.modelSupportsImages)
|
|
5501
5506
|
content.push({ type: "text", text: `Image available at ${imagePath}; this host model does not support image attachments.` });
|
|
5507
|
+
else {
|
|
5508
|
+
const maxSourceBytes = Math.floor(remainingImageBytes / 4) * 3;
|
|
5509
|
+
let data;
|
|
5510
|
+
if (maxSourceBytes > 0 && (await stat(imagePath)).size <= maxSourceBytes) {
|
|
5511
|
+
const chunks = [];
|
|
5512
|
+
let sourceBytes = 0;
|
|
5513
|
+
const stream = createReadStream(imagePath, { end: maxSourceBytes, signal: opts.signal });
|
|
5514
|
+
for await (const chunk of stream) {
|
|
5515
|
+
sourceBytes += chunk.length;
|
|
5516
|
+
if (sourceBytes > maxSourceBytes)
|
|
5517
|
+
break;
|
|
5518
|
+
chunks.push(chunk);
|
|
5519
|
+
}
|
|
5520
|
+
opts.signal?.throwIfAborted();
|
|
5521
|
+
if (sourceBytes <= maxSourceBytes)
|
|
5522
|
+
data = Buffer.concat(chunks, sourceBytes).toString("base64");
|
|
5523
|
+
}
|
|
5524
|
+
opts.signal?.throwIfAborted();
|
|
5525
|
+
if (data === undefined)
|
|
5526
|
+
content.push({ type: "text", text: `Image available at ${imagePath}; attachment omitted because it would exceed the 32 MiB image attachment budget for this result.` });
|
|
5527
|
+
else {
|
|
5528
|
+
remainingImageBytes -= data.length;
|
|
5529
|
+
content.push({ type: "image", data, mimeType });
|
|
5530
|
+
}
|
|
5531
|
+
}
|
|
5502
5532
|
}
|
|
5503
5533
|
}
|
|
5504
5534
|
return { content, details: { readSeekValue: { tool: opts.tool, ok: true, path: filePath, envelope, presentation } } };
|
|
@@ -5566,7 +5596,7 @@ function registerAccessTools(pi, options = {}) {
|
|
|
5566
5596
|
const summary = summaryLine(presentation.summary, { hidden: hasExpandable && !expanded, theme, style: hasWarning ? "warning" : "success" });
|
|
5567
5597
|
return renderShowPresentation(summary, presentation.body, extras, expanded, theme, width);
|
|
5568
5598
|
}
|
|
5569
|
-
const nonShowSummary = resolveNonShowSummary(
|
|
5599
|
+
const nonShowSummary = resolveNonShowSummary(result.details?.readSeekValue);
|
|
5570
5600
|
const summary = summaryLine(nonShowSummary, { hidden: !!text && !expanded, theme, style: "success" });
|
|
5571
5601
|
return new Text7(clampLinesToWidth((expanded ? `${summary}
|
|
5572
5602
|
${text}` : summary).split(`
|
|
@@ -5650,7 +5680,7 @@ function piReadSeekExtension(pi) {
|
|
|
5650
5680
|
onFileAnchored: (absolutePath) => sessionAnchors.markAnchored(absolutePath),
|
|
5651
5681
|
name: readName,
|
|
5652
5682
|
toolAliases,
|
|
5653
|
-
imageMode:
|
|
5683
|
+
imageMode: resolveReadSeekImageMode()
|
|
5654
5684
|
});
|
|
5655
5685
|
registerWriteTool(pi, {
|
|
5656
5686
|
onFileAnchored: (absolutePath) => sessionAnchors.markAnchored(absolutePath),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-readseek",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.6",
|
|
4
4
|
"description": "Pi extension for LINE:HASH-anchored file operations and structural code navigation",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -39,8 +39,8 @@
|
|
|
39
39
|
"node": ">=20.0.0"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@jarkkojs/readseek": "^0.12.
|
|
43
|
-
"@jarkkojs/readseek-api": "^0.12.
|
|
42
|
+
"@jarkkojs/readseek": "^0.12.6",
|
|
43
|
+
"@jarkkojs/readseek-api": "^0.12.6",
|
|
44
44
|
"diff": "^9.0.0",
|
|
45
45
|
"xxhash-wasm": "^1.1.0"
|
|
46
46
|
},
|