webfox 4.9.0 → 4.11.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.
Files changed (47) hide show
  1. package/README.md +4 -12
  2. package/dist/{adapter-UIFBJKKF.js → adapter-44ZBIK47.js} +4 -6
  3. package/dist/{adapter-HTMXAJTU.js → adapter-57MELLYI.js} +2 -8
  4. package/dist/{adapter-VMMS4YQG.js → adapter-BZO5UEI6.js} +3 -15
  5. package/dist/{adapter-OK2PTP6R.js → adapter-D4EXZEDL.js} +16 -48
  6. package/dist/{adapter-G3I7JEO5.js → adapter-DJCTEEOA.js} +3 -5
  7. package/dist/{adapter-764OQFKY.js → adapter-DLNMW34W.js} +8 -35
  8. package/dist/{adapter-HRI5ZMGK.js → adapter-GFXYSHKP.js} +9 -43
  9. package/dist/{adapter-2UVAARTV.js → adapter-GJOUFE2U.js} +1 -1
  10. package/dist/{adapter-C2VZHFUB.js → adapter-MZ7USB6Q.js} +3 -4
  11. package/dist/adapter-ODDFBGJG.js +167 -0
  12. package/dist/{adapter-K6AMSUCR.js → adapter-QQZFHUOP.js} +14 -37
  13. package/dist/{adapter-AUYLTDPM.js → adapter-RR55EZAW.js} +1 -1
  14. package/dist/adapter-SZMVKAMC.js +91 -0
  15. package/dist/{adapter-6EZAIE65.js → adapter-VXT4C6RZ.js} +16 -66
  16. package/dist/{adapter-L6BFKWGX.js → adapter-WXEVTCM3.js} +7 -14
  17. package/dist/{adapter-VW4FMMJC.js → adapter-XSQX3GAI.js} +13 -5
  18. package/dist/{adapter-QIP32KA4.js → adapter-XU2APKPC.js} +3 -3
  19. package/dist/{adapter-A5WYGGZI.js → adapter-YVZ4YBK5.js} +8 -16
  20. package/dist/chunk-6RQGO727.js +71 -0
  21. package/dist/{chunk-HCYQF24V.js → chunk-KMUCUJVN.js} +3 -3
  22. package/dist/{chunk-EF4VMDZL.js → chunk-LDVDVA4Z.js} +1 -4
  23. package/dist/{chunk-GPACLYNT.js → chunk-NENL6L6N.js} +2 -0
  24. package/dist/{chunk-LTJOWNI2.js → chunk-PVNWACMT.js} +199 -17
  25. package/dist/{chunk-YZXM4U2C.js → chunk-TYJ6RHKB.js} +10 -0
  26. package/dist/{chunk-QZFN2747.js → chunk-YILOS4E7.js} +23 -9
  27. package/dist/cli.js +5 -5
  28. package/dist/config.schema.json +299 -0
  29. package/dist/contents.d.ts +5 -0
  30. package/dist/document-schema.d.ts +17 -5
  31. package/dist/domain.d.ts +14 -2
  32. package/dist/durable.js +5 -5
  33. package/dist/index.js +4 -4
  34. package/dist/pi.js +33 -14
  35. package/dist/providers/contract.d.ts +12 -1
  36. package/dist/providers/keenable/adapter.d.ts +5 -0
  37. package/dist/providers/keenable/definition.d.ts +1 -0
  38. package/dist/providers/keenable/types.d.ts +4 -0
  39. package/dist/providers/registry.d.ts +2 -0
  40. package/dist/providers/sofya/adapter.d.ts +8 -0
  41. package/dist/providers/sofya/definition.d.ts +1 -0
  42. package/dist/providers/sofya/types.d.ts +4 -0
  43. package/dist/render.d.ts +8 -2
  44. package/docs/provider.md +44 -0
  45. package/examples/custom/README.md +9 -3
  46. package/package.json +1 -1
  47. package/dist/chunk-BTWECET5.js +0 -31
@@ -5,6 +5,7 @@ export declare const providers: {
5
5
  readonly exa: import("./definition.js").ProviderDefinitionFor<"exa">;
6
6
  readonly firecrawl: import("./definition.js").ProviderDefinitionFor<"firecrawl">;
7
7
  readonly gemini: import("./definition.js").ProviderDefinitionFor<"gemini">;
8
+ readonly keenable: import("./definition.js").ProviderDefinitionFor<"keenable">;
8
9
  readonly linkup: import("./definition.js").ProviderDefinitionFor<"linkup">;
9
10
  readonly ollama: import("./definition.js").ProviderDefinitionFor<"ollama">;
10
11
  readonly openai: import("./definition.js").ProviderDefinitionFor<"openai">;
@@ -12,6 +13,7 @@ export declare const providers: {
12
13
  readonly perplexity: import("./definition.js").ProviderDefinitionFor<"perplexity">;
13
14
  readonly serpbase: import("./definition.js").ProviderDefinitionFor<"serpbase">;
14
15
  readonly serper: import("./definition.js").ProviderDefinitionFor<"serper">;
16
+ readonly sofya: import("./definition.js").ProviderDefinitionFor<"sofya">;
15
17
  readonly tavily: import("./definition.js").ProviderDefinitionFor<"tavily">;
16
18
  readonly valyu: import("./definition.js").ProviderDefinitionFor<"valyu">;
17
19
  readonly youcom: import("./definition.js").ProviderDefinitionFor<"youcom">;
@@ -0,0 +1,8 @@
1
+ import type { ProviderContext, ProviderRequest, SearchResponse, ToolOutput } from "../contract.js";
2
+ import type { Sofya } from "./types.js";
3
+ export declare const adapter: {
4
+ search(request: ProviderRequest<"search">, config: Sofya, context: ProviderContext): Promise<SearchResponse>;
5
+ contents(request: ProviderRequest<"contents">, config: Sofya, context: ProviderContext): Promise<import("../../contents.js").IndexedContentsResponse>;
6
+ answer(request: ProviderRequest<"answer">, config: Sofya, context: ProviderContext): Promise<ToolOutput>;
7
+ research(request: ProviderRequest<"research">, config: Sofya, context: ProviderContext): Promise<ToolOutput>;
8
+ };
@@ -0,0 +1 @@
1
+ export declare const sofyaProvider: import("../definition.js").ProviderDefinitionFor<"sofya">;
@@ -0,0 +1,4 @@
1
+ import type { Provider } from "../contract.js";
2
+ export interface Sofya extends Provider {
3
+ baseUrl?: string;
4
+ }
package/dist/render.d.ts CHANGED
@@ -1,5 +1,11 @@
1
- import type { WebDocument } from "./domain.js";
2
- /** Presentation is deliberately outside the application/runtime. */
1
+ import type { Capability, SearchResult, Source, WebDocument } from "./domain.js";
2
+ /**
3
+ * Presentation is deliberately outside the application/runtime: providers
4
+ * return empty results as data, and only renderers decide how they look.
5
+ */
6
+ export declare function emptyResultText(capability: Capability): string;
7
+ /** Label a search result or source by its title, falling back to its URL. */
8
+ export declare function resultLabel(result: SearchResult | Source): string;
3
9
  export declare function renderTextDocument(document: WebDocument, { includeErrors }?: {
4
10
  includeErrors?: boolean;
5
11
  }): string;
package/docs/provider.md CHANGED
@@ -123,6 +123,23 @@ The research agent is fixed; answer model settings don't affect it.
123
123
  If you previously selected Gemini for search, choose a search-capable provider
124
124
  and remove `providers.gemini.options.search` from your configuration.
125
125
 
126
+ ## Keenable
127
+
128
+ Supports search. Set `KEENABLE_API_KEY`, or configure
129
+ `providers.keenable.credentials.api` with a credential source. No defaults change
130
+ unless you select Keenable.
131
+
132
+ ```sh
133
+ web search "Node.js release notes" --provider keenable \
134
+ --site nodejs.org --published-after 30d
135
+ web config default search keenable
136
+ ```
137
+
138
+ Keenable caps `maxResults` at 50. Native options include `mode` (`pro` or
139
+ `realtime`), `site`, `published_after`/`published_before`,
140
+ `acquired_after`/`acquired_before`, `query_time`, and `snippet_max_length`.
141
+ Time filters accept dates, ISO 8601 timestamps, or relative deltas such as `7d`.
142
+
126
143
  ## Linkup
127
144
 
128
145
  Supports search, page extraction, and research. Set `LINKUP_API_KEY`.
@@ -323,6 +340,33 @@ Supports search. Set `SERPER_API_KEY`.
323
340
  web search "Node.js release notes" --provider serper
324
341
  ```
325
342
 
343
+ ## Sofya
344
+
345
+ Supports search, page extraction, answers, and research. Set `SOFYA_API_KEY`,
346
+ or configure `providers.sofya.credentials.api` with a credential source. No
347
+ defaults change unless you select Sofya.
348
+
349
+ ```sh
350
+ web search "Node.js release notes" --provider sofya --freshness month
351
+ web contents https://nodejs.org/en/blog --provider sofya
352
+ web answer "What is the latest Node.js LTS?" --provider sofya
353
+ web research "State of WebAssembly outside the browser" --provider sofya
354
+ web config default search sofya
355
+ ```
356
+
357
+ Search caps `maxResults` at 20 and defaults to `search_depth: "snippets"`;
358
+ `basic` also reads each page and returns its text in `metadata.content`. Native
359
+ options include `topic` (`general` or `news`), `freshness` (`day`, `week`,
360
+ `month`, `year`, or a `YYYY-MM-DD:YYYY-MM-DD` range), and
361
+ `include_domains`/`exclude_domains`. Answers come from a search with
362
+ `include_answer` and report Sofya's `altered_query` or `relaxed_query` in
363
+ metadata. Contents accepts `include_raw_html`. Research accepts `topic`,
364
+ `freshness`, and `max_sources` (5-30) and usually takes 20-60 seconds.
365
+
366
+ Sofya calls can take up to 60 seconds, so search, contents, and answers have a
367
+ 90-second overall deadline by default. An explicit CLI `--timeout`, library
368
+ `timeoutMs`, or YAML `execution.timeoutMs` takes precedence.
369
+
326
370
  ## You.com
327
371
 
328
372
  Supports search. Set `YDC_API_KEY`; the library, CLI, and Pi extension use the
@@ -32,10 +32,16 @@ Payloads and responses:
32
32
 
33
33
  | Capability | Input | Response |
34
34
  | --- | --- | --- |
35
- | Search | `{ "query": "...", "maxResults": 5 }` | `{ "results": [{ "title": "...", "url": "https://...", "snippet": "..." }] }` |
35
+ | Search | `{ "query": "...", "maxResults": 5 }` | `{ "results": [{ "title": "...", "url": "https://...", "snippet": "..." }] }` (`title` is optional) |
36
36
  | Contents | `{ "urls": ["https://..."] }` | `{ "answers": [{ "inputIndex": 0, "url": "https://...", "content": "..." }] }` |
37
- | Answer | `{ "query": "..." }` | `{ "text": "..." }` |
38
- | Research | `{ "input": "..." }` | `{ "text": "..." }` |
37
+ | Answer | `{ "query": "..." }` | `{ "text": "...", "sources": [{ "url": "https://...", "title": "..." }] }` |
38
+ | Research | `{ "input": "..." }` | `{ "text": "...", "sources": [{ "url": "https://...", "title": "..." }] }` |
39
+
40
+ Return results as data and leave presentation to webfox. Empty results are
41
+ valid: return no search results, an empty `text`, or a page without `content`
42
+ instead of placeholder text. Omit titles you don't have rather than repeating
43
+ the URL. `sources` is optional; webfox drops sources that have neither a `url`
44
+ nor a `title`.
39
45
 
40
46
  Contents answers must cover every request index exactly once. `inputIndex`
41
47
  associates a response with the requested URL; `url` can hold a redirected URL.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "webfox",
3
- "version": "4.9.0",
3
+ "version": "4.11.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": [
@@ -1,31 +0,0 @@
1
- // src/render.ts
2
- function renderTextDocument(document, { includeErrors = true } = {}) {
3
- return document.results.map((entry, index) => {
4
- const heading = document.results.length > 1 ? `## ${index + 1}. ${entry.input}` : "";
5
- if (!entry.ok)
6
- return includeErrors ? [heading, `Error: ${entry.error.message}`].filter(Boolean).join("\n\n") : void 0;
7
- let body;
8
- if ("results" in entry.value)
9
- body = entry.value.results.length ? entry.value.results.map(
10
- (result, i) => `${i + 1}. ${result.title}
11
- ${result.url}
12
- ${result.snippet.replaceAll("\n", "\n ")}`
13
- ).join("\n\n") : "No results found.";
14
- else if ("text" in entry.value) body = entry.value.text;
15
- else body = renderContents(entry.value);
16
- return [heading, body].filter(Boolean).join("\n\n");
17
- }).filter((part) => part !== void 0).join("\n\n");
18
- }
19
- function renderContents(answer) {
20
- return [
21
- `## ${answer.url}`,
22
- answer.content,
23
- answer.summary === void 0 ? void 0 : `### Summary
24
-
25
- ${typeof answer.summary === "string" ? answer.summary : JSON.stringify(answer.summary, null, 2)}`
26
- ].filter(Boolean).join("\n\n");
27
- }
28
-
29
- export {
30
- renderTextDocument
31
- };