webfox 4.2.1 → 4.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.js CHANGED
@@ -6,18 +6,20 @@ import {
6
6
  resolveConfigPath,
7
7
  setCapabilityDefault,
8
8
  validateConfig
9
- } from "./chunk-SGHBA2PZ.js";
9
+ } from "./chunk-5H6OAJCS.js";
10
10
  import "./chunk-WCTOYZVB.js";
11
11
  import {
12
- CONFIG_SCHEMA_URL,
12
+ CONFIG_SCHEMA_URL
13
+ } from "./chunk-4SX4TI7A.js";
14
+ import {
13
15
  validateConfiguredOptions
14
- } from "./chunk-TJWQTB6W.js";
16
+ } from "./chunk-VYMIR35R.js";
15
17
  import "./chunk-ZVTVERW5.js";
16
18
  import {
17
19
  CAPABILITIES,
18
20
  PROVIDER_IDS,
19
21
  WEBFOX_ERROR_CODES
20
- } from "./chunk-WVHMWLKU.js";
22
+ } from "./chunk-GPACLYNT.js";
21
23
  import {
22
24
  WebfoxError
23
25
  } from "./chunk-U4BLULLV.js";
package/dist/pi.js CHANGED
@@ -1,16 +1,17 @@
1
1
  import {
2
2
  renderTextDocument
3
- } from "./chunk-QRHDXM2L.js";
3
+ } from "./chunk-BTWECET5.js";
4
4
  import {
5
5
  createWebfox,
6
6
  resolveConfigPath
7
- } from "./chunk-SGHBA2PZ.js";
7
+ } from "./chunk-5H6OAJCS.js";
8
8
  import "./chunk-WCTOYZVB.js";
9
- import "./chunk-TJWQTB6W.js";
9
+ import "./chunk-4SX4TI7A.js";
10
+ import "./chunk-VYMIR35R.js";
10
11
  import "./chunk-ZVTVERW5.js";
11
12
  import {
12
13
  CAPABILITIES
13
- } from "./chunk-WVHMWLKU.js";
14
+ } from "./chunk-GPACLYNT.js";
14
15
  import {
15
16
  WebfoxError
16
17
  } from "./chunk-U4BLULLV.js";
@@ -267,7 +268,7 @@ function statusRows(details) {
267
268
  return inputs;
268
269
  }
269
270
  function displayInput(value) {
270
- return JSON.stringify(plainText(value)).slice(1, -1);
271
+ return JSON.stringify(plainText(value)).slice(1, -1).replaceAll('\\"', '"');
271
272
  }
272
273
  var WebCall = class {
273
274
  constructor(capability) {
@@ -499,7 +500,12 @@ function webExtension(pi) {
499
500
  pi.registerTool({
500
501
  name: `web_${capability}`,
501
502
  label: `Web ${capability[0].toUpperCase()}${capability.slice(1)}`,
502
- description: `${descriptions[capability]} Output is truncated to 2000 lines or 50 KiB; full results are saved to a file when truncated.`,
503
+ // Keep provider guidance with the tool schema, including with custom system prompts.
504
+ description: [
505
+ descriptions[capability],
506
+ ...inspection.promptGuidelines ?? [],
507
+ "Output is truncated to 2000 lines or 50 KiB; full results are saved to a file when truncated."
508
+ ].join("\n"),
503
509
  parameters,
504
510
  prepareArguments(args) {
505
511
  return prepareToolArguments(parameters, args);
@@ -81,6 +81,7 @@ export interface ProviderConfigMap {
81
81
  openai: import("./openai/types.js").OpenAI;
82
82
  parallel: import("./parallel/types.js").Parallel;
83
83
  perplexity: import("./perplexity/types.js").Perplexity;
84
+ serpbase: import("./serpbase/types.js").SerpBase;
84
85
  serper: import("./serper/types.js").Serper;
85
86
  tavily: import("./tavily/types.js").Tavily;
86
87
  valyu: import("./valyu/types.js").Valyu;
@@ -3,11 +3,15 @@ import type { CredentialSource, ProviderConfiguration } from "../configuration/t
3
3
  import type { ProviderConfigMap, ProviderContext, ProviderRequest, ProviderResult } from "./contract.js";
4
4
  import type { ProviderCredentialMetadata } from "./metadata.js";
5
5
  export interface CapabilityDefinition {
6
+ /** Overall deadline when neither the request nor execution configuration sets one. */
7
+ defaultTimeoutMs?: number;
6
8
  options?: Record<string, unknown>;
7
9
  limits?: {
8
10
  maxResults?: number;
9
11
  };
10
12
  promptGuidelines?: readonly string[];
13
+ /** Allowed option keys per mode; switching modes drops incompatible inherited defaults. */
14
+ modeOptionKeys?: Readonly<Record<string, readonly string[]>>;
11
15
  /** Whether the entire operation may be repeated after a transient failure. */
12
16
  retrySafe: boolean;
13
17
  }
@@ -10,6 +10,7 @@ export declare const providers: {
10
10
  readonly openai: import("./definition.js").ProviderDefinitionFor<"openai">;
11
11
  readonly parallel: import("./definition.js").ProviderDefinitionFor<"parallel">;
12
12
  readonly perplexity: import("./definition.js").ProviderDefinitionFor<"perplexity">;
13
+ readonly serpbase: import("./definition.js").ProviderDefinitionFor<"serpbase">;
13
14
  readonly serper: import("./definition.js").ProviderDefinitionFor<"serper">;
14
15
  readonly tavily: import("./definition.js").ProviderDefinitionFor<"tavily">;
15
16
  readonly valyu: import("./definition.js").ProviderDefinitionFor<"valyu">;
@@ -0,0 +1,5 @@
1
+ import type { ProviderContext, ProviderRequest, SearchResponse } from "../contract.js";
2
+ import { type SerpBase } from "./types.js";
3
+ export declare const adapter: {
4
+ search(request: ProviderRequest<"search">, config: SerpBase, context: ProviderContext): Promise<SearchResponse>;
5
+ };
@@ -0,0 +1 @@
1
+ export declare const serpbaseProvider: import("../definition.js").ProviderDefinitionFor<"serpbase">;
@@ -0,0 +1,37 @@
1
+ import type { Provider } from "../contract.js";
2
+ export declare const SERPBASE_MODES: {
3
+ readonly search: {
4
+ readonly path: "search";
5
+ readonly result: "organic";
6
+ readonly options: readonly ["hl", "gl", "page", "device"];
7
+ };
8
+ readonly images: {
9
+ readonly path: "images";
10
+ readonly result: "images";
11
+ readonly options: readonly ["hl", "gl", "page"];
12
+ };
13
+ readonly news: {
14
+ readonly path: "news";
15
+ readonly result: "news";
16
+ readonly options: readonly ["hl", "gl", "page"];
17
+ };
18
+ readonly videos: {
19
+ readonly path: "videos";
20
+ readonly result: "videos";
21
+ readonly options: readonly ["hl", "gl", "page"];
22
+ };
23
+ readonly maps: {
24
+ readonly path: "maps/search";
25
+ readonly result: "places";
26
+ readonly options: readonly ["hl", "gl", "page", "lat", "lng", "zoom"];
27
+ };
28
+ readonly "maps-detail": {
29
+ readonly path: "maps/detail";
30
+ readonly result: "place";
31
+ readonly options: readonly ["hl", "gl"];
32
+ };
33
+ };
34
+ export type SerpBaseMode = keyof typeof SERPBASE_MODES;
35
+ export interface SerpBase extends Provider {
36
+ baseUrl?: string;
37
+ }
package/docs/provider.md CHANGED
@@ -152,6 +152,108 @@ Supports search, grounded answers, and research. Set `PERPLEXITY_API_KEY`.
152
152
  web answer "What is MCP?" --provider perplexity
153
153
  ```
154
154
 
155
+ ## SerpBase
156
+
157
+ Supports all six Google endpoints through the existing `search` capability and
158
+ Pi's `web_search` tool. Set `SERPBASE_API_KEY`, or configure
159
+ `providers.serpbase.credentials.api` with a credential source. No defaults change
160
+ unless you select SerpBase.
161
+
162
+ ```sh
163
+ web search "Node.js release notes" --provider serpbase --gl us --hl en --device pc
164
+ web config default search serpbase
165
+ ```
166
+
167
+ Choose a mode with `--mode` in the CLI or `options.mode` in the library and Pi:
168
+
169
+ | Mode | Input | Results and controls |
170
+ | --- | --- | --- |
171
+ | `search` (default) | Search text | Organic results; `device` is `default`, `pc`, or `mobile`. |
172
+ | `images` | Search text | Image URLs, source pages, and thumbnails. |
173
+ | `news` | Search text | Articles, publishers, and published-time text. |
174
+ | `videos` | Search text | Videos, sources, durations, and published-time text. |
175
+ | `maps` | Place search text | Places, addresses, ratings, and feature IDs; optional `lat`, `lng`, and `zoom`. |
176
+ | `maps-detail` | Feature IDs from `maps` | One place's details per input, including contact information and hours when available. |
177
+
178
+ SerpBase has a 120-second overall deadline by default because some endpoints can
179
+ exceed the usual 30-second search deadline. An explicit CLI `--timeout`, library
180
+ `timeoutMs`, or YAML `execution.timeoutMs` takes precedence. This deadline includes
181
+ all inputs and retries; it isn't a separate allowance per request. Other providers
182
+ keep their existing defaults.
183
+
184
+ Every mode accepts `hl` (language, default `en`) and `gl` (country, default `us`).
185
+ All modes except `maps-detail` accept `page` (1-based, default `1`). Maps Search
186
+ requires `lat` and `lng` together. `zoom` requires coordinates, ranges from `1` to
187
+ `21`, and defaults to `14` upstream when coordinates are supplied. Device
188
+ selection applies only to organic search; `default` lets SerpBase choose.
189
+
190
+ ```sh
191
+ web search "architecture diagrams" --provider serpbase --mode images
192
+ web search "Node.js releases" --provider serpbase --mode news
193
+ web search "Node.js tutorials" --provider serpbase --mode videos
194
+ web search "coffee" --provider serpbase --mode maps --lat 52.52 --lng 13.405 --zoom 14
195
+ ```
196
+
197
+ For place enrichment, copy a `feature_id` from a Maps result and pass it as the
198
+ search input. Don't use a place name, `place_id`, CID, or Maps URL:
199
+
200
+ ```sh
201
+ web search '0x...:0x...' --provider serpbase --mode maps-detail
202
+ ```
203
+
204
+ Replace the placeholder with an actual returned ID. The model follows the same
205
+ sequence using the same tool, with one feature ID per `queries` entry:
206
+
207
+ ```json
208
+ {
209
+ "queries": ["0x...:0x..."],
210
+ "options": { "mode": "maps-detail" }
211
+ }
212
+ ```
213
+
214
+ Save provider-specific defaults under `providers.serpbase.options.search`:
215
+
216
+ ```yaml
217
+ providers:
218
+ serpbase:
219
+ options:
220
+ search:
221
+ gl: de
222
+ hl: de
223
+ device: pc
224
+ ```
225
+
226
+ Changing modes drops incompatible inherited defaults. For example, a request
227
+ with `mode: images` doesn't inherit the configured `device: pc`. Explicitly
228
+ supplying incompatible options is an error, not a silently ignored setting.
229
+ Coordinate dependencies are checked after merging defaults and request options.
230
+
231
+ Each input fetches only the selected page or place, preserving result order.
232
+ `maxResults` trims that page locally; it doesn't increase the upstream page size
233
+ or fetch additional pages. Use `--page 2` to request another page explicitly.
234
+ Requests can incur charges, including retries after transient failures. See the
235
+ [SerpBase API reference](https://serpbase.dev/docs) for per-endpoint pricing.
236
+
237
+ Text and model-visible output include actionable fields: image/source URLs,
238
+ news/video sources and time text, and place feature IDs, addresses, contact
239
+ information, ratings, and hours when returned. Images aren't downloaded. Published
240
+ times and opening status are upstream observations, not independently verified.
241
+ Ambiguous clock-like video times are labeled `Time (upstream)`, not publication
242
+ dates or inferred durations. The known Google navigation-logo artifact is
243
+ excluded from image results; other results retain their upstream order.
244
+
245
+ JSON output retains original ranks, aliases, sitelinks, media fields, and place
246
+ data in `metadata`, alongside the selected `mode`. Ranks are page-relative, not
247
+ calculated absolute positions. `metadata.searchContext` includes the returned
248
+ page, query, request ID, charged credits, and rich SERP modules when available.
249
+ Context is attached to results, so an empty results list has no context metadata.
250
+ Rich modules aren't mixed into the primary result ordering.
251
+
252
+ The provider uses the JSON API directly, without an SDK dependency.
253
+ `providers.serpbase.baseUrl` can replace the API origin for a compatible proxy;
254
+ webfox appends the selected endpoint, such as `/google/images` or
255
+ `/google/maps/detail`.
256
+
155
257
  ## Serper
156
258
 
157
259
  Supports search. Set `SERPER_API_KEY`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "webfox",
3
- "version": "4.2.1",
3
+ "version": "4.3.0",
4
4
  "description": "Search the web, extract pages, get grounded answers, and run deep research with the web CLI, a TypeScript library, and a pi extension. Bring your own providers and API keys.",
5
5
  "type": "module",
6
6
  "files": [