@f5xc-salesdemos/xcsh 17.3.0 → 17.4.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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@f5xc-salesdemos/xcsh",
4
- "version": "17.3.0",
4
+ "version": "17.4.0",
5
5
  "description": "Coding agent CLI with read, bash, edit, write tools and session management",
6
6
  "homepage": "https://github.com/f5xc-salesdemos/xcsh",
7
7
  "author": "Can Boluk",
@@ -46,12 +46,12 @@
46
46
  "dependencies": {
47
47
  "@agentclientprotocol/sdk": "0.16.1",
48
48
  "@mozilla/readability": "^0.6",
49
- "@f5xc-salesdemos/xcsh-stats": "17.3.0",
50
- "@f5xc-salesdemos/pi-agent-core": "17.3.0",
51
- "@f5xc-salesdemos/pi-ai": "17.3.0",
52
- "@f5xc-salesdemos/pi-natives": "17.3.0",
53
- "@f5xc-salesdemos/pi-tui": "17.3.0",
54
- "@f5xc-salesdemos/pi-utils": "17.3.0",
49
+ "@f5xc-salesdemos/xcsh-stats": "17.4.0",
50
+ "@f5xc-salesdemos/pi-agent-core": "17.4.0",
51
+ "@f5xc-salesdemos/pi-ai": "17.4.0",
52
+ "@f5xc-salesdemos/pi-natives": "17.4.0",
53
+ "@f5xc-salesdemos/pi-tui": "17.4.0",
54
+ "@f5xc-salesdemos/pi-utils": "17.4.0",
55
55
  "@sinclair/typebox": "^0.34",
56
56
  "@xterm/headless": "^6.0",
57
57
  "ajv": "^8.18",
@@ -1313,6 +1313,15 @@ export const SETTINGS_SCHEMA = {
1313
1313
  default: true,
1314
1314
  ui: { tab: "tools", label: "Web Search", description: "Enable the web_search tool for web searching" },
1315
1315
  },
1316
+ "web_search.verbose": {
1317
+ type: "boolean",
1318
+ default: false,
1319
+ ui: {
1320
+ tab: "tools",
1321
+ label: "Web Search Verbose",
1322
+ description: "Show detailed search panels (sources, metadata, tokens). When disabled, uses compact output.",
1323
+ },
1324
+ },
1316
1325
 
1317
1326
  "browser.enabled": {
1318
1327
  type: "boolean",
@@ -192,6 +192,7 @@ async function executeSearch(
192
192
  for (const provider of providers) {
193
193
  lastProvider = provider;
194
194
  try {
195
+ const searchStart = performance.now();
195
196
  const response = await provider.search({
196
197
  query: params.query.replace(/202\d/g, String(new Date().getFullYear())), // LUL
197
198
  limit: params.limit,
@@ -205,6 +206,7 @@ async function executeSearch(
205
206
  maxUses: params.max_uses,
206
207
  userLocation: params.user_location,
207
208
  });
209
+ response.durationMs = performance.now() - searchStart;
208
210
 
209
211
  const text = formatForLLM(response);
210
212
 
@@ -6,6 +6,7 @@
6
6
 
7
7
  import type { Component } from "@f5xc-salesdemos/pi-tui";
8
8
  import { Text, visibleWidth, wrapTextWithAnsi } from "@f5xc-salesdemos/pi-tui";
9
+ import { Settings } from "../../config/settings";
9
10
  import type { RenderResultOptions } from "../../extensibility/custom-tools/types";
10
11
  import type { Theme } from "../../modes/theme/theme";
11
12
  import {
@@ -25,6 +26,14 @@ import { CachedOutputBlock } from "../../tui/output-block";
25
26
  import { getSearchProvider } from "./provider";
26
27
  import type { SearchResponse } from "./types";
27
28
 
29
+ function getVerboseSetting(): boolean {
30
+ try {
31
+ return Settings.instance.get("web_search.verbose");
32
+ } catch {
33
+ return false;
34
+ }
35
+ }
36
+
28
37
  const MAX_COLLAPSED_ANSWER_LINES = PREVIEW_LIMITS.COLLAPSED_LINES;
29
38
  const MAX_EXPANDED_ANSWER_LINES = PREVIEW_LIMITS.EXPANDED_LINES;
30
39
  const MAX_ANSWER_LINE_LEN = TRUNCATE_LENGTHS.LINE;
@@ -92,6 +101,20 @@ export function renderSearchResult(
92
101
  return renderFallbackText(rawText, options.expanded, theme);
93
102
  }
94
103
 
104
+ const verbose = getVerboseSetting();
105
+ if (!verbose) {
106
+ const searches = response.usage?.searchRequests ?? 1;
107
+ const plural = searches !== 1 ? "es" : "";
108
+ const dur =
109
+ response.durationMs !== undefined
110
+ ? response.durationMs >= 1000
111
+ ? `${Math.round(response.durationMs / 1000)}s`
112
+ : `${Math.round(response.durationMs)}ms`
113
+ : "";
114
+ const line = ` \u23BF Did ${searches} search${plural}${dur ? ` in ${dur}` : ""}`;
115
+ return new Text(theme.fg("dim", line), 0, 0);
116
+ }
117
+
95
118
  const sources = Array.isArray(response.sources) ? response.sources : [];
96
119
  const sourceCount = sources.length;
97
120
  const citations = Array.isArray(response.citations) ? response.citations : [];
@@ -288,6 +311,10 @@ export function renderSearchCall(
288
311
  theme: Theme,
289
312
  ): Component {
290
313
  const query = truncateToWidth(args.query ?? "", 80);
314
+ const verbose = getVerboseSetting();
315
+ if (!verbose) {
316
+ return new Text(`${theme.fg("text", `Web Search("${query}")`)}`, 0, 0);
317
+ }
291
318
  const text = renderStatusLine({ icon: "pending", title: "Web Search", description: query }, theme);
292
319
  return new Text(text, 0, 0);
293
320
  }
@@ -94,6 +94,8 @@ export interface SearchResponse {
94
94
  requestId?: string;
95
95
  /** Authentication mode used by the provider (e.g. oauth, api-key) */
96
96
  authMode?: string;
97
+ /** Wall-clock duration of the search request in milliseconds */
98
+ durationMs?: number;
97
99
  }
98
100
 
99
101
  /** Provider-specific error with optional HTTP status */