llmist 17.2.1 → 17.3.0
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/dist/index.cjs +157 -36
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -10
- package/dist/index.d.ts +4 -10
- package/dist/index.js +157 -36
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -5821,10 +5821,14 @@ interface StoredOutput {
|
|
|
5821
5821
|
gadgetName: string;
|
|
5822
5822
|
/** Full output content */
|
|
5823
5823
|
content: string;
|
|
5824
|
+
/** Total character count of the stored content */
|
|
5825
|
+
charCount: number;
|
|
5824
5826
|
/** Size in bytes */
|
|
5825
5827
|
byteSize: number;
|
|
5826
5828
|
/** Number of lines */
|
|
5827
5829
|
lineCount: number;
|
|
5830
|
+
/** Length of the longest line in characters */
|
|
5831
|
+
maxLineLength: number;
|
|
5828
5832
|
/** When the output was stored */
|
|
5829
5833
|
timestamp: Date;
|
|
5830
5834
|
}
|
|
@@ -8564,19 +8568,9 @@ declare function resultWithFile(result: string, fileData: Buffer | Uint8Array, m
|
|
|
8564
8568
|
/**
|
|
8565
8569
|
* Create a GadgetOutputViewer gadget instance bound to a specific output store.
|
|
8566
8570
|
*
|
|
8567
|
-
* This is a factory function because the gadget needs access to the output store,
|
|
8568
|
-
* which is created per-agent-run.
|
|
8569
|
-
*
|
|
8570
8571
|
* @param store - The GadgetOutputStore to read outputs from
|
|
8571
8572
|
* @param maxOutputChars - Maximum characters to return (default: 76,800 = ~19k tokens)
|
|
8572
8573
|
* @returns A GadgetOutputViewer gadget instance
|
|
8573
|
-
*
|
|
8574
|
-
* @example
|
|
8575
|
-
* ```typescript
|
|
8576
|
-
* const store = new GadgetOutputStore();
|
|
8577
|
-
* const viewer = createGadgetOutputViewer(store, 76_800);
|
|
8578
|
-
* registry.register("GadgetOutputViewer", viewer);
|
|
8579
|
-
* ```
|
|
8580
8574
|
*/
|
|
8581
8575
|
declare function createGadgetOutputViewer(store: GadgetOutputStore, maxOutputChars?: number): AbstractGadget;
|
|
8582
8576
|
|
package/dist/index.d.ts
CHANGED
|
@@ -5821,10 +5821,14 @@ interface StoredOutput {
|
|
|
5821
5821
|
gadgetName: string;
|
|
5822
5822
|
/** Full output content */
|
|
5823
5823
|
content: string;
|
|
5824
|
+
/** Total character count of the stored content */
|
|
5825
|
+
charCount: number;
|
|
5824
5826
|
/** Size in bytes */
|
|
5825
5827
|
byteSize: number;
|
|
5826
5828
|
/** Number of lines */
|
|
5827
5829
|
lineCount: number;
|
|
5830
|
+
/** Length of the longest line in characters */
|
|
5831
|
+
maxLineLength: number;
|
|
5828
5832
|
/** When the output was stored */
|
|
5829
5833
|
timestamp: Date;
|
|
5830
5834
|
}
|
|
@@ -8564,19 +8568,9 @@ declare function resultWithFile(result: string, fileData: Buffer | Uint8Array, m
|
|
|
8564
8568
|
/**
|
|
8565
8569
|
* Create a GadgetOutputViewer gadget instance bound to a specific output store.
|
|
8566
8570
|
*
|
|
8567
|
-
* This is a factory function because the gadget needs access to the output store,
|
|
8568
|
-
* which is created per-agent-run.
|
|
8569
|
-
*
|
|
8570
8571
|
* @param store - The GadgetOutputStore to read outputs from
|
|
8571
8572
|
* @param maxOutputChars - Maximum characters to return (default: 76,800 = ~19k tokens)
|
|
8572
8573
|
* @returns A GadgetOutputViewer gadget instance
|
|
8573
|
-
*
|
|
8574
|
-
* @example
|
|
8575
|
-
* ```typescript
|
|
8576
|
-
* const store = new GadgetOutputStore();
|
|
8577
|
-
* const viewer = createGadgetOutputViewer(store, 76_800);
|
|
8578
|
-
* registry.register("GadgetOutputViewer", viewer);
|
|
8579
|
-
* ```
|
|
8580
8574
|
*/
|
|
8581
8575
|
declare function createGadgetOutputViewer(store: GadgetOutputStore, maxOutputChars?: number): AbstractGadget;
|
|
8582
8576
|
|
package/dist/index.js
CHANGED
|
@@ -4654,6 +4654,9 @@ var init_create_gadget = __esm({
|
|
|
4654
4654
|
|
|
4655
4655
|
// src/gadgets/output-viewer.ts
|
|
4656
4656
|
import { z as z3 } from "zod";
|
|
4657
|
+
function pluralize(count, singular, plural = `${singular}s`) {
|
|
4658
|
+
return count === 1 ? singular : plural;
|
|
4659
|
+
}
|
|
4657
4660
|
function applyPattern(lines, pattern) {
|
|
4658
4661
|
const regex = new RegExp(pattern.regex);
|
|
4659
4662
|
if (!pattern.include) {
|
|
@@ -4678,80 +4681,169 @@ function applyPatterns(lines, patterns) {
|
|
|
4678
4681
|
}
|
|
4679
4682
|
return result;
|
|
4680
4683
|
}
|
|
4681
|
-
function
|
|
4684
|
+
function parseLimitWindow(limit) {
|
|
4682
4685
|
const trimmed = limit.trim();
|
|
4683
4686
|
if (trimmed.endsWith("-") && !trimmed.startsWith("-")) {
|
|
4684
4687
|
const n = parseInt(trimmed.slice(0, -1), 10);
|
|
4685
|
-
if (!isNaN(n) && n > 0) {
|
|
4686
|
-
return
|
|
4688
|
+
if (!Number.isNaN(n) && n > 0) {
|
|
4689
|
+
return { kind: "first", count: n };
|
|
4687
4690
|
}
|
|
4688
4691
|
}
|
|
4689
4692
|
if (trimmed.startsWith("-") && !trimmed.includes("-", 1)) {
|
|
4690
4693
|
const n = parseInt(trimmed, 10);
|
|
4691
|
-
if (!isNaN(n) && n < 0) {
|
|
4692
|
-
return
|
|
4694
|
+
if (!Number.isNaN(n) && n < 0) {
|
|
4695
|
+
return { kind: "last", count: Math.abs(n) };
|
|
4693
4696
|
}
|
|
4694
4697
|
}
|
|
4695
4698
|
const rangeMatch = trimmed.match(/^(\d+)-(\d+)$/);
|
|
4696
4699
|
if (rangeMatch) {
|
|
4697
4700
|
const start = parseInt(rangeMatch[1], 10);
|
|
4698
4701
|
const end = parseInt(rangeMatch[2], 10);
|
|
4699
|
-
if (!isNaN(start) && !isNaN(end) && start > 0 && end >= start) {
|
|
4700
|
-
return
|
|
4702
|
+
if (!Number.isNaN(start) && !Number.isNaN(end) && start > 0 && end >= start) {
|
|
4703
|
+
return { kind: "range", start, end };
|
|
4701
4704
|
}
|
|
4702
4705
|
}
|
|
4703
|
-
return
|
|
4706
|
+
return null;
|
|
4707
|
+
}
|
|
4708
|
+
function applyLineLimit(lines, limit) {
|
|
4709
|
+
const window = parseLimitWindow(limit);
|
|
4710
|
+
if (!window) return lines;
|
|
4711
|
+
switch (window.kind) {
|
|
4712
|
+
case "first":
|
|
4713
|
+
return lines.slice(0, window.count);
|
|
4714
|
+
case "last":
|
|
4715
|
+
return lines.slice(-window.count);
|
|
4716
|
+
case "range":
|
|
4717
|
+
return lines.slice(window.start - 1, window.end);
|
|
4718
|
+
}
|
|
4719
|
+
}
|
|
4720
|
+
function applyCharacterLimit(content, limit, maxOutputChars) {
|
|
4721
|
+
const total = content.length;
|
|
4722
|
+
if (total === 0) {
|
|
4723
|
+
return { text: "", start: 0, end: 0, total: 0, truncatedBySize: false, hasMoreAfter: false };
|
|
4724
|
+
}
|
|
4725
|
+
let startIndex = 0;
|
|
4726
|
+
let endExclusive = total;
|
|
4727
|
+
const window = limit ? parseLimitWindow(limit) : null;
|
|
4728
|
+
if (window) {
|
|
4729
|
+
switch (window.kind) {
|
|
4730
|
+
case "first":
|
|
4731
|
+
endExclusive = Math.min(window.count, total);
|
|
4732
|
+
break;
|
|
4733
|
+
case "last":
|
|
4734
|
+
startIndex = Math.max(0, total - window.count);
|
|
4735
|
+
break;
|
|
4736
|
+
case "range":
|
|
4737
|
+
startIndex = Math.min(window.start - 1, total);
|
|
4738
|
+
endExclusive = Math.min(window.end, total);
|
|
4739
|
+
break;
|
|
4740
|
+
}
|
|
4741
|
+
}
|
|
4742
|
+
let text3 = content.slice(startIndex, endExclusive);
|
|
4743
|
+
let truncatedBySize = false;
|
|
4744
|
+
if (text3.length > maxOutputChars) {
|
|
4745
|
+
text3 = window?.kind === "last" ? text3.slice(-maxOutputChars) : text3.slice(0, maxOutputChars);
|
|
4746
|
+
if (window?.kind === "last") {
|
|
4747
|
+
startIndex = endExclusive - text3.length;
|
|
4748
|
+
}
|
|
4749
|
+
truncatedBySize = true;
|
|
4750
|
+
}
|
|
4751
|
+
return {
|
|
4752
|
+
text: text3,
|
|
4753
|
+
start: text3.length === 0 ? 0 : startIndex + 1,
|
|
4754
|
+
end: text3.length === 0 ? 0 : startIndex + text3.length,
|
|
4755
|
+
total,
|
|
4756
|
+
truncatedBySize,
|
|
4757
|
+
hasMoreAfter: startIndex + text3.length < total
|
|
4758
|
+
};
|
|
4759
|
+
}
|
|
4760
|
+
function buildCharacterRangeHint(start, total) {
|
|
4761
|
+
if (total <= 0 || start > total) return null;
|
|
4762
|
+
const end = Math.min(total, start + CHARACTER_HINT_WINDOW - 1);
|
|
4763
|
+
return `${start}-${end}`;
|
|
4764
|
+
}
|
|
4765
|
+
function buildCharacterModeSuggestion(stored, opts = {}) {
|
|
4766
|
+
const hint = buildCharacterRangeHint(opts.start ?? 1, stored.charCount);
|
|
4767
|
+
const action = opts.removePatterns ? "Remove patterns and then try" : "Try";
|
|
4768
|
+
const lineLabel = pluralize(stored.lineCount, "line");
|
|
4769
|
+
return `This output is dense (${stored.lineCount.toLocaleString()} ${lineLabel}; longest line ${stored.maxLineLength.toLocaleString()} chars). ${action} mode: "character"` + (hint ? `, limit: "${hint}"` : "") + ".";
|
|
4770
|
+
}
|
|
4771
|
+
function shouldSuggestCharacterMode(stored, maxOutputChars = DEFAULT_MAX_OUTPUT_CHARS) {
|
|
4772
|
+
return stored.lineCount <= 3 && (stored.maxLineLength > maxOutputChars || stored.maxLineLength >= DENSE_LINE_THRESHOLD);
|
|
4704
4773
|
}
|
|
4705
4774
|
function createGadgetOutputViewer(store, maxOutputChars = DEFAULT_MAX_OUTPUT_CHARS) {
|
|
4706
4775
|
return createGadget({
|
|
4707
4776
|
name: "GadgetOutputViewer",
|
|
4708
|
-
description:
|
|
4777
|
+
description: 'View stored output from gadgets that returned too much data. Use mode "line" for grep-like filtering and mode "character" for raw chunked browsing when the output is dense or effectively single-line. Patterns work only in line mode.',
|
|
4709
4778
|
schema: z3.object({
|
|
4710
4779
|
id: z3.string().describe("ID of the stored output (from the truncation message)"),
|
|
4780
|
+
mode: z3.enum(["line", "character"]).default("line").describe(
|
|
4781
|
+
'Browse by "line" (supports patterns) or by "character" (raw windows for dense output).'
|
|
4782
|
+
),
|
|
4711
4783
|
patterns: z3.array(patternSchema).optional().describe(
|
|
4712
|
-
|
|
4784
|
+
'Line-mode filter patterns applied in order (like piping through grep). Not supported in mode "character".'
|
|
4713
4785
|
),
|
|
4714
4786
|
limit: z3.string().optional().describe(
|
|
4715
|
-
"
|
|
4787
|
+
`Pagination window. In mode "line" it is a line range; in mode "character" it is a character range. Formats: "100-" (first 100), "-25" (last 25), "50-100" (inclusive range).`
|
|
4716
4788
|
)
|
|
4717
4789
|
}),
|
|
4718
4790
|
examples: [
|
|
4719
4791
|
{
|
|
4720
4792
|
comment: "View first 50 lines of stored output",
|
|
4721
|
-
params: { id: "Search_abc12345", limit: "50-" }
|
|
4793
|
+
params: { id: "Search_abc12345", mode: "line", limit: "50-" }
|
|
4722
4794
|
},
|
|
4723
4795
|
{
|
|
4724
4796
|
comment: "Filter for error lines with context",
|
|
4725
4797
|
params: {
|
|
4726
4798
|
id: "Search_abc12345",
|
|
4799
|
+
mode: "line",
|
|
4727
4800
|
patterns: [{ regex: "error|Error|ERROR", include: true, before: 2, after: 5 }]
|
|
4728
4801
|
}
|
|
4729
4802
|
},
|
|
4730
4803
|
{
|
|
4731
|
-
comment: "Exclude blank lines, then show first 100",
|
|
4804
|
+
comment: "Exclude blank lines, then show first 100 lines",
|
|
4732
4805
|
params: {
|
|
4733
4806
|
id: "Search_abc12345",
|
|
4807
|
+
mode: "line",
|
|
4734
4808
|
patterns: [{ regex: "^\\s*$", include: false, before: 0, after: 0 }],
|
|
4735
4809
|
limit: "100-"
|
|
4736
4810
|
}
|
|
4737
4811
|
},
|
|
4738
4812
|
{
|
|
4739
|
-
comment: "
|
|
4813
|
+
comment: "Browse the raw output by character window when line mode is too dense",
|
|
4740
4814
|
params: {
|
|
4741
4815
|
id: "Search_abc12345",
|
|
4742
|
-
|
|
4743
|
-
|
|
4744
|
-
{ regex: "test|spec", include: false, before: 0, after: 0 }
|
|
4745
|
-
],
|
|
4746
|
-
limit: "50-"
|
|
4816
|
+
mode: "character",
|
|
4817
|
+
limit: "1-2000"
|
|
4747
4818
|
}
|
|
4748
4819
|
}
|
|
4749
4820
|
],
|
|
4750
|
-
execute: ({ id, patterns, limit }) => {
|
|
4821
|
+
execute: ({ id, mode, patterns, limit }) => {
|
|
4751
4822
|
const stored = store.get(id);
|
|
4752
4823
|
if (!stored) {
|
|
4753
4824
|
return `Error: No stored output with id "${id}". Available IDs: ${store.getIds().join(", ") || "(none)"}`;
|
|
4754
4825
|
}
|
|
4826
|
+
const suggestCharacterMode = shouldSuggestCharacterMode(stored, maxOutputChars);
|
|
4827
|
+
if (mode === "character") {
|
|
4828
|
+
if (patterns && patterns.length > 0) {
|
|
4829
|
+
return 'Error: patterns are only supported in mode "line". Remove patterns or switch back to mode: "line".';
|
|
4830
|
+
}
|
|
4831
|
+
const window = applyCharacterLimit(stored.content, limit, maxOutputChars);
|
|
4832
|
+
if (window.total === 0) {
|
|
4833
|
+
return "[Mode: character | Output is empty]";
|
|
4834
|
+
}
|
|
4835
|
+
const header2 = [
|
|
4836
|
+
`[Mode: character | Showing chars ${window.start.toLocaleString()}-${window.end.toLocaleString()} of ${window.total.toLocaleString()}${window.truncatedBySize ? " (truncated due to viewer size limit)" : ""}]`
|
|
4837
|
+
];
|
|
4838
|
+
if (window.hasMoreAfter) {
|
|
4839
|
+
const nextRange = buildCharacterRangeHint(window.end + 1, window.total);
|
|
4840
|
+
if (nextRange) {
|
|
4841
|
+
header2.push(`[Next chunk: mode: "character", limit: "${nextRange}"]`);
|
|
4842
|
+
}
|
|
4843
|
+
}
|
|
4844
|
+
return `${header2.join("\n")}
|
|
4845
|
+
${window.text}`;
|
|
4846
|
+
}
|
|
4755
4847
|
let lines = stored.content.split("\n");
|
|
4756
4848
|
if (patterns && patterns.length > 0) {
|
|
4757
4849
|
lines = applyPatterns(
|
|
@@ -4767,54 +4859,76 @@ function createGadgetOutputViewer(store, maxOutputChars = DEFAULT_MAX_OUTPUT_CHA
|
|
|
4767
4859
|
if (limit) {
|
|
4768
4860
|
lines = applyLineLimit(lines, limit);
|
|
4769
4861
|
}
|
|
4770
|
-
let output = lines.join("\n");
|
|
4771
4862
|
const totalLines = stored.lineCount;
|
|
4863
|
+
const totalLineLabel = pluralize(totalLines, "line");
|
|
4772
4864
|
const returnedLines = lines.length;
|
|
4773
4865
|
if (returnedLines === 0) {
|
|
4774
|
-
|
|
4866
|
+
const base = `No lines matched the filters. Original output had ${totalLines.toLocaleString()} lines.`;
|
|
4867
|
+
if (!suggestCharacterMode) return base;
|
|
4868
|
+
return `${base} ${buildCharacterModeSuggestion(stored, {
|
|
4869
|
+
removePatterns: Boolean(patterns && patterns.length > 0)
|
|
4870
|
+
})}`;
|
|
4775
4871
|
}
|
|
4872
|
+
let output = lines.join("\n");
|
|
4776
4873
|
let truncatedBySize = false;
|
|
4777
4874
|
let linesIncluded = returnedLines;
|
|
4875
|
+
let clippedFirstLine = false;
|
|
4778
4876
|
if (output.length > maxOutputChars) {
|
|
4779
4877
|
truncatedBySize = true;
|
|
4780
4878
|
let truncatedOutput = "";
|
|
4781
4879
|
linesIncluded = 0;
|
|
4782
4880
|
for (const line of lines) {
|
|
4783
|
-
|
|
4784
|
-
|
|
4881
|
+
const addition = linesIncluded === 0 ? line : `
|
|
4882
|
+
${line}`;
|
|
4883
|
+
if (truncatedOutput.length + addition.length > maxOutputChars) break;
|
|
4884
|
+
truncatedOutput += addition;
|
|
4785
4885
|
linesIncluded++;
|
|
4786
4886
|
}
|
|
4887
|
+
if (linesIncluded === 0) {
|
|
4888
|
+
clippedFirstLine = true;
|
|
4889
|
+
linesIncluded = 1;
|
|
4890
|
+
truncatedOutput = lines[0].slice(0, maxOutputChars);
|
|
4891
|
+
}
|
|
4787
4892
|
output = truncatedOutput;
|
|
4788
4893
|
}
|
|
4789
4894
|
let header;
|
|
4790
|
-
if (
|
|
4895
|
+
if (clippedFirstLine) {
|
|
4896
|
+
header = `[Mode: line | Showing 1 partial line of ${totalLines.toLocaleString()} ${totalLineLabel} (the selected line exceeds the viewer size limit)]
|
|
4897
|
+
`;
|
|
4898
|
+
} else if (truncatedBySize) {
|
|
4791
4899
|
const remainingLines = returnedLines - linesIncluded;
|
|
4792
|
-
header = `[Showing ${linesIncluded} of ${totalLines}
|
|
4793
|
-
[... ${remainingLines.toLocaleString()} more
|
|
4900
|
+
header = `[Mode: line | Showing ${linesIncluded.toLocaleString()} of ${totalLines.toLocaleString()} ${totalLineLabel} (truncated due to size limit)]
|
|
4901
|
+
[... ${remainingLines.toLocaleString()} more ${pluralize(remainingLines, "line")}. Use limit parameter to paginate, e.g., limit: "${linesIncluded + 1}-${linesIncluded + 200}"]
|
|
4794
4902
|
`;
|
|
4795
4903
|
} else if (returnedLines < totalLines) {
|
|
4796
|
-
header = `[Showing ${returnedLines} of ${totalLines}
|
|
4904
|
+
header = `[Mode: line | Showing ${returnedLines.toLocaleString()} of ${totalLines.toLocaleString()} ${totalLineLabel}]
|
|
4797
4905
|
`;
|
|
4798
4906
|
} else {
|
|
4799
|
-
header = `[Showing all ${totalLines}
|
|
4907
|
+
header = `[Mode: line | Showing all ${totalLines.toLocaleString()} ${totalLineLabel}]
|
|
4800
4908
|
`;
|
|
4801
4909
|
}
|
|
4802
|
-
|
|
4910
|
+
const footer = suggestCharacterMode || clippedFirstLine ? `
|
|
4911
|
+
[Tip: ${buildCharacterModeSuggestion(stored, {
|
|
4912
|
+
removePatterns: Boolean(patterns && patterns.length > 0)
|
|
4913
|
+
})}]` : "";
|
|
4914
|
+
return header + output + footer;
|
|
4803
4915
|
}
|
|
4804
4916
|
});
|
|
4805
4917
|
}
|
|
4806
|
-
var
|
|
4918
|
+
var DEFAULT_MAX_OUTPUT_CHARS, CHARACTER_HINT_WINDOW, DENSE_LINE_THRESHOLD, patternSchema;
|
|
4807
4919
|
var init_output_viewer = __esm({
|
|
4808
4920
|
"src/gadgets/output-viewer.ts"() {
|
|
4809
4921
|
"use strict";
|
|
4810
4922
|
init_create_gadget();
|
|
4923
|
+
DEFAULT_MAX_OUTPUT_CHARS = 76800;
|
|
4924
|
+
CHARACTER_HINT_WINDOW = 2e3;
|
|
4925
|
+
DENSE_LINE_THRESHOLD = 4e3;
|
|
4811
4926
|
patternSchema = z3.object({
|
|
4812
4927
|
regex: z3.string().describe("Regular expression to match"),
|
|
4813
4928
|
include: z3.boolean().default(true).describe("true = keep matching lines, false = exclude matching lines"),
|
|
4814
4929
|
before: z3.number().int().min(0).default(0).describe("Context lines before each match (like grep -B)"),
|
|
4815
4930
|
after: z3.number().int().min(0).default(0).describe("Context lines after each match (like grep -A)")
|
|
4816
4931
|
});
|
|
4817
|
-
DEFAULT_MAX_OUTPUT_CHARS = 76800;
|
|
4818
4932
|
}
|
|
4819
4933
|
});
|
|
4820
4934
|
|
|
@@ -4836,12 +4950,15 @@ var init_gadget_output_store = __esm({
|
|
|
4836
4950
|
store(gadgetName, content) {
|
|
4837
4951
|
const id = this.generateId(gadgetName);
|
|
4838
4952
|
const encoder = new TextEncoder();
|
|
4953
|
+
const lines = content.split("\n");
|
|
4839
4954
|
const stored = {
|
|
4840
4955
|
id,
|
|
4841
4956
|
gadgetName,
|
|
4842
4957
|
content,
|
|
4958
|
+
charCount: content.length,
|
|
4843
4959
|
byteSize: encoder.encode(content).length,
|
|
4844
|
-
lineCount:
|
|
4960
|
+
lineCount: lines.length,
|
|
4961
|
+
maxLineLength: lines.reduce((max, line) => Math.max(max, line.length), 0),
|
|
4845
4962
|
timestamp: /* @__PURE__ */ new Date()
|
|
4846
4963
|
};
|
|
4847
4964
|
this.outputs.set(id, stored);
|
|
@@ -4945,16 +5062,20 @@ var init_output_limit_manager = __esm({
|
|
|
4945
5062
|
}
|
|
4946
5063
|
if (result.length > this.charLimit) {
|
|
4947
5064
|
const id = this.outputStore.store(ctx.gadgetName, result);
|
|
4948
|
-
const
|
|
4949
|
-
const
|
|
5065
|
+
const stored = this.outputStore.get(id);
|
|
5066
|
+
const lines = stored?.lineCount ?? result.split("\n").length;
|
|
5067
|
+
const bytes = stored?.byteSize ?? new TextEncoder().encode(result).length;
|
|
5068
|
+
const denseSuggestion = stored && shouldSuggestCharacterMode(stored, this.charLimit) ? ` ${buildCharacterModeSuggestion(stored)}` : "";
|
|
4950
5069
|
this.logger.info("Gadget output exceeded limit, stored for browsing", {
|
|
4951
5070
|
gadgetName: ctx.gadgetName,
|
|
4952
5071
|
outputId: id,
|
|
4953
5072
|
bytes,
|
|
4954
5073
|
lines,
|
|
5074
|
+
charCount: stored?.charCount,
|
|
5075
|
+
maxLineLength: stored?.maxLineLength,
|
|
4955
5076
|
charLimit: this.charLimit
|
|
4956
5077
|
});
|
|
4957
|
-
return `[Gadget "${ctx.gadgetName}" returned too much data: ${bytes.toLocaleString()} bytes, ${lines.toLocaleString()} lines. Use GadgetOutputViewer with id "${id}" to read it]
|
|
5078
|
+
return `[Gadget "${ctx.gadgetName}" returned too much data: ${bytes.toLocaleString()} bytes, ${lines.toLocaleString()} lines. Use GadgetOutputViewer with id "${id}" to read it.]` + denseSuggestion;
|
|
4958
5079
|
}
|
|
4959
5080
|
return result;
|
|
4960
5081
|
};
|