@zeldrisho/pi-web-search 0.14.4 → 0.14.5

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/CHANGELOG.md CHANGED
@@ -7,6 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.14.5] - 2026-11-01
11
+
12
+ ### Changed
13
+
14
+ - Shorten search guidance, error, and output-limit notices.
15
+
16
+ ### Fixed
17
+
18
+ - Avoid duplicate overflow notices in expanded search results.
19
+
10
20
  ## [0.14.4] - 2026-10-30
11
21
 
12
22
  ### Changed
@@ -196,7 +206,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
196
206
 
197
207
  - Add bounded Brave web search ([cbc9491](https://github.com/zeldrisho/pi-packages/commit/cbc9491dce36555ab91b6bef203ec8b380596a89))
198
208
 
199
- [Unreleased]: https://github.com/zeldrisho/pi-packages/compare/pi-web-search-v0.14.4...HEAD
209
+ [Unreleased]: https://github.com/zeldrisho/pi-packages/compare/pi-web-search-v0.14.5...HEAD
210
+ [0.14.5]: https://github.com/zeldrisho/pi-packages/compare/pi-web-search-v0.14.4...pi-web-search-v0.14.5
200
211
  [0.14.4]: https://github.com/zeldrisho/pi-packages/compare/pi-web-search-v0.14.3...pi-web-search-v0.14.4
201
212
  [0.14.3]: https://github.com/zeldrisho/pi-packages/compare/pi-web-search-v0.14.2...pi-web-search-v0.14.3
202
213
  [0.14.2]: https://github.com/zeldrisho/pi-packages/compare/pi-web-search-v0.14.1...pi-web-search-v0.14.2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zeldrisho/pi-web-search",
3
- "version": "0.14.4",
3
+ "version": "0.14.5",
4
4
  "description": "Pi extension for bounded Brave web search with generated-answer fallback",
5
5
  "keywords": [
6
6
  "brave-search",
@@ -34,8 +34,8 @@
34
34
  "@earendil-works/pi-tui": "^1.4.0",
35
35
  "typebox": "^1.4.2",
36
36
  "typescript": "^7.0.2",
37
- "vite": "npm:@voidzero-dev/vite-plus-core@1.3.0",
38
- "vite-plus": "1.3.0"
37
+ "vite": "npm:@voidzero-dev/vite-plus-core@1.4.0",
38
+ "vite-plus": "1.4.0"
39
39
  },
40
40
  "peerDependencies": {
41
41
  "@earendil-works/pi-coding-agent": "*",
package/src/index.ts CHANGED
@@ -72,14 +72,26 @@ export default function (pi: ExtensionAPI) {
72
72
 
73
73
  if (isPartial) return new Text(theme.fg("warning", content?.text || "Searching…"), 0, 0);
74
74
 
75
+ const path = result.details?.fullOutputPath;
76
+ const lastLine = content?.text.trimEnd().split("\n").at(-1);
77
+
78
+ const overflowNotice =
79
+ path &&
80
+ lastLine?.endsWith(`Full output: ${path}]`) &&
81
+ (lastLine.startsWith("[Output truncated:") ||
82
+ lastLine.startsWith("[Structured payload omitted due to limits."))
83
+ ? lastLine
84
+ : undefined;
85
+
75
86
  return content?.type === "text"
76
87
  ? renderCollapsibleOutput(
77
88
  content.text,
78
89
  expanded,
79
90
  theme,
80
91
  context?.isError,
81
- result.details?.fullOutputPath
82
- ? `[${result.details.truncation?.truncated ? "Output truncated. " : "Structured payload omitted. "}Full output: ${result.details.fullOutputPath}]`
92
+ path
93
+ ? (overflowNotice ??
94
+ `[${result.details?.truncation?.truncated ? "Output truncated. " : "Structured payload omitted. "}Full output: ${path}]`)
83
95
  : undefined,
84
96
  )
85
97
  : new Text(theme.fg("dim", "No results"), 0, 0);
package/src/provider.ts CHANGED
@@ -146,15 +146,14 @@ export async function requestText(
146
146
  // Preserve the useful HTTP status when an untrusted error body cannot be read.
147
147
  }
148
148
 
149
- throw new Error(`Search provider returned HTTP ${response.status}${body ? `: ${body}` : ""}`);
149
+ throw new Error(`Provider returned HTTP ${response.status}${body ? `: ${body}` : ""}`);
150
150
  }
151
151
 
152
152
  return await readResponseText(response, SEARCH_MAX_RESPONSE_BYTES);
153
153
  } catch (error) {
154
- if (timedOut)
155
- throw new Error(`Web search timed out after ${REQUEST_TIMEOUT_MS / 1000} seconds.`);
154
+ if (timedOut) throw new Error(`Timed out after ${REQUEST_TIMEOUT_MS / 1000} seconds.`);
156
155
 
157
- if (signal?.aborted) throw new Error("Web search was cancelled.");
156
+ if (signal?.aborted) throw new Error("Cancelled.");
158
157
  throw error;
159
158
  } finally {
160
159
  clearTimeout(timeout);
package/src/render.ts CHANGED
@@ -37,7 +37,7 @@ export function renderCollapsibleOutput(
37
37
  );
38
38
  }
39
39
 
40
- if (warning) {
40
+ if (warning && !visible.includes(warning)) {
41
41
  component.addChild(new Spacer(1));
42
42
  component.addChild(new Text(theme.fg("warning", warning), 0, 0));
43
43
  }
package/src/search.ts CHANGED
@@ -159,16 +159,13 @@ function escapeMarkdownLinkText(value: string): string {
159
159
  function formatResults(query: string, results: SearchResult[], requestedCount: number): string {
160
160
  const returnedCount = results.length;
161
161
 
162
- const retryAdvice =
163
- "If evidence is insufficient, fetch promising sources or broaden the query (fewer quotes; relax nonessential site: restrictions).";
164
-
165
162
  const guidance =
166
163
  returnedCount < requestedCount
167
- ? `Returned ${returnedCount} of ${requestedCount} requested results. ${retryAdvice} Preserve required source restrictions.`
164
+ ? `Returned ${returnedCount}/${requestedCount} results. If needed, read relevant pages or broaden the query; keep required site restrictions.`
168
165
  : "";
169
166
 
170
167
  if (returnedCount === 0) {
171
- return `No web results found for ${JSON.stringify(query)}. Broaden the query (fewer quotes; relax nonessential site: restrictions). Preserve required source restrictions. No results do not prove absence.`;
168
+ return `No web results for ${JSON.stringify(query)}. Try broadening the query; keep required site restrictions. No results do not prove absence.`;
172
169
  }
173
170
 
174
171
  const entries = results.map((result, index) => {
@@ -466,7 +463,7 @@ export class SearchRuntime {
466
463
  return entry;
467
464
  },
468
465
  signal,
469
- "Web search was cancelled.",
466
+ "Cancelled.",
470
467
  ));
471
468
 
472
469
  if (payload.results.length === 0 && !payload.answer) {
@@ -508,7 +505,7 @@ export class SearchRuntime {
508
505
  return entry;
509
506
  },
510
507
  signal,
511
- "Web search was cancelled.",
508
+ "Cancelled.",
512
509
  ));
513
510
  cached = cachedAnswer !== undefined;
514
511
  apiKeySource = answerCredentials.source;
@@ -598,8 +595,8 @@ export class SearchRuntime {
598
595
  }
599
596
 
600
597
  text += truncation.truncated
601
- ? `\n\n[Output truncated to ${truncation.outputLines} of ${truncation.totalLines} lines (${formatSize(truncation.outputBytes)} of ${formatSize(truncation.totalBytes)}). Full output saved to: ${fullOutputPath}]`
602
- : `\n\n[Structured payload omitted to fit output limits. Full output saved to: ${fullOutputPath}]`;
598
+ ? `\n\n[Output truncated: ${truncation.outputLines}/${truncation.totalLines} lines (${formatSize(truncation.outputBytes)}/${formatSize(truncation.totalBytes)}). Full output: ${fullOutputPath}]`
599
+ : `\n\n[Structured payload omitted due to limits. Full output: ${fullOutputPath}]`;
603
600
  }
604
601
 
605
602
  structured.fullOutputPath = fullOutputPath;