webfox 0.0.0-test.0 → 4.0.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/LICENSE +21 -0
- package/README.md +256 -3
- package/assets/webfox-lockup-dark.png +0 -0
- package/assets/webfox-lockup.png +0 -0
- package/dist/adapter-2YBFCBCZ.js +161 -0
- package/dist/adapter-67TIISDW.js +753 -0
- package/dist/adapter-AB7LKV7N.js +324 -0
- package/dist/adapter-AUYLTDPM.js +73 -0
- package/dist/adapter-HITGYUXN.js +494 -0
- package/dist/adapter-HPTMLH75.js +334 -0
- package/dist/adapter-I6OUKBZQ.js +492 -0
- package/dist/adapter-ISZQTZDP.js +166 -0
- package/dist/adapter-MAG7X663.js +230 -0
- package/dist/adapter-NEXSOHGT.js +232 -0
- package/dist/adapter-PADXKW43.js +162 -0
- package/dist/adapter-SDQX2533.js +123 -0
- package/dist/adapter-UAZNLDSS.js +237 -0
- package/dist/adapter-XBAQSK7I.js +282 -0
- package/dist/application-types.d.ts +34 -0
- package/dist/application.d.ts +2 -0
- package/dist/chunk-EF4VMDZL.js +85 -0
- package/dist/chunk-G2YAQEET.js +38 -0
- package/dist/chunk-I2UIACY3.js +12 -0
- package/dist/chunk-L425U55P.js +3051 -0
- package/dist/chunk-QRHDXM2L.js +31 -0
- package/dist/chunk-SMF5ALX7.js +762 -0
- package/dist/chunk-U4BLULLV.js +52 -0
- package/dist/chunk-WCTOYZVB.js +85 -0
- package/dist/chunk-X6ZBIHZC.js +21 -0
- package/dist/chunk-YZXM4U2C.js +21 -0
- package/dist/chunk-ZVTVERW5.js +20 -0
- package/dist/cli.js +641 -0
- package/dist/config.schema.json +4270 -0
- package/dist/configuration/defaults.d.ts +3 -0
- package/dist/configuration/file.d.ts +17 -0
- package/dist/configuration/options-schema.d.ts +2 -0
- package/dist/configuration/planning.d.ts +10 -0
- package/dist/configuration/schema.d.ts +9 -0
- package/dist/configuration/types.d.ts +37 -0
- package/dist/contents.d.ts +19 -0
- package/dist/domain.d.ts +89 -0
- package/dist/errors.d.ts +17 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +38 -0
- package/dist/package-metadata.d.ts +3 -0
- package/dist/pi-keybindings.d.ts +1 -0
- package/dist/pi-params.d.ts +3 -0
- package/dist/pi-render.d.ts +50 -0
- package/dist/pi-search-render.d.ts +4 -0
- package/dist/pi-text.d.ts +4 -0
- package/dist/pi-validation.d.ts +4 -0
- package/dist/pi.d.ts +2 -0
- package/dist/pi.js +563 -0
- package/dist/providers/brave/adapter.d.ts +7 -0
- package/dist/providers/brave/definition.d.ts +1 -0
- package/dist/providers/brave/types.d.ts +4 -0
- package/dist/providers/cli-json.d.ts +9 -0
- package/dist/providers/cloudflare/adapter.d.ts +5 -0
- package/dist/providers/cloudflare/definition.d.ts +1 -0
- package/dist/providers/cloudflare/types.d.ts +4 -0
- package/dist/providers/contract.d.ts +88 -0
- package/dist/providers/custom/adapter.d.ts +9 -0
- package/dist/providers/custom/definition.d.ts +1 -0
- package/dist/providers/custom/types.d.ts +9 -0
- package/dist/providers/definition.d.ts +32 -0
- package/dist/providers/exa/adapter.d.ts +8 -0
- package/dist/providers/exa/definition.d.ts +1 -0
- package/dist/providers/exa/types.d.ts +4 -0
- package/dist/providers/firecrawl/adapter.d.ts +7 -0
- package/dist/providers/firecrawl/definition.d.ts +1 -0
- package/dist/providers/firecrawl/types.d.ts +4 -0
- package/dist/providers/gemini/adapter.d.ts +14 -0
- package/dist/providers/gemini/definition.d.ts +1 -0
- package/dist/providers/gemini/types.d.ts +3 -0
- package/dist/providers/linkup/adapter.d.ts +7 -0
- package/dist/providers/linkup/definition.d.ts +1 -0
- package/dist/providers/linkup/types.d.ts +4 -0
- package/dist/providers/metadata.d.ts +15 -0
- package/dist/providers/ollama/adapter.d.ts +6 -0
- package/dist/providers/ollama/definition.d.ts +1 -0
- package/dist/providers/ollama/types.d.ts +4 -0
- package/dist/providers/openai/adapter.d.ts +7 -0
- package/dist/providers/openai/definition.d.ts +1 -0
- package/dist/providers/openai/types.d.ts +28 -0
- package/dist/providers/parallel/adapter.d.ts +6 -0
- package/dist/providers/parallel/definition.d.ts +1 -0
- package/dist/providers/parallel/types.d.ts +4 -0
- package/dist/providers/perplexity/adapter.d.ts +7 -0
- package/dist/providers/perplexity/definition.d.ts +1 -0
- package/dist/providers/perplexity/types.d.ts +4 -0
- package/dist/providers/registry.d.ts +16 -0
- package/dist/providers/serper/adapter.d.ts +5 -0
- package/dist/providers/serper/definition.d.ts +1 -0
- package/dist/providers/serper/types.d.ts +21 -0
- package/dist/providers/shared.d.ts +4 -0
- package/dist/providers/tavily/adapter.d.ts +6 -0
- package/dist/providers/tavily/definition.d.ts +1 -0
- package/dist/providers/tavily/types.d.ts +4 -0
- package/dist/providers/valyu/adapter.d.ts +8 -0
- package/dist/providers/valyu/definition.d.ts +1 -0
- package/dist/providers/valyu/types.d.ts +4 -0
- package/dist/render.d.ts +5 -0
- package/dist/runtime/credentials.d.ts +15 -0
- package/dist/runtime/duration.d.ts +2 -0
- package/dist/runtime/execute.d.ts +20 -0
- package/dist/runtime/lifecycle.d.ts +8 -0
- package/dist/runtime/outward.d.ts +11 -0
- package/dist/runtime/polling.d.ts +13 -0
- package/dist/runtime/process.d.ts +4 -0
- package/docs/cli-experience.md +177 -0
- package/docs/provider.md +177 -0
- package/docs/reference.md +181 -0
- package/example-config.yaml +36 -0
- package/examples/custom/README.md +57 -0
- package/examples/custom/provider.mjs +54 -0
- package/examples/custom/webfox.json +18 -0
- package/package.json +122 -8
- package/index.js +0 -2
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
# CLI reference
|
|
2
|
+
|
|
3
|
+
Install the `webfox` package to use the `web` executable. Start with the
|
|
4
|
+
[README](../README.md) for setup and everyday examples.
|
|
5
|
+
|
|
6
|
+
## Commands and help
|
|
7
|
+
|
|
8
|
+
```sh
|
|
9
|
+
web --help
|
|
10
|
+
web search --help
|
|
11
|
+
web search --provider openai --help
|
|
12
|
+
web providers
|
|
13
|
+
web providers openai
|
|
14
|
+
web config default search brave
|
|
15
|
+
web config path
|
|
16
|
+
web config show
|
|
17
|
+
web config validate
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Ordinary help shows all command controls. Explicit provider help adds that
|
|
21
|
+
provider's exact supported flags. For example, OpenAI exposes `--model`,
|
|
22
|
+
`--search-context-size`, and `--user-location-country`. Arrays use repeatable
|
|
23
|
+
flags; booleans provide `--foo` and `--no-foo`.
|
|
24
|
+
|
|
25
|
+
Root and capability help end with copyable examples. Help highlights headings,
|
|
26
|
+
commands, flags, and arguments on a terminal. Piped help stays plain;
|
|
27
|
+
`NO_COLOR` or `--no-color` disables styling.
|
|
28
|
+
|
|
29
|
+
## Inputs
|
|
30
|
+
|
|
31
|
+
Search and answer accept up to ten independent queries or questions. Quote each
|
|
32
|
+
input; results keep input order. Research accepts exactly one brief. Contents
|
|
33
|
+
accepts one or more URLs.
|
|
34
|
+
|
|
35
|
+
```sh
|
|
36
|
+
web search "Node.js cancellation" "Bun cancellation"
|
|
37
|
+
web answer "What is MCP?" "What is A2A?" --provider openai
|
|
38
|
+
web contents https://example.com/a https://example.com/b --provider tavily
|
|
39
|
+
web research "Compare databases" --provider gemini --timeout 20m
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Omit positional input to read piped or redirected stdin:
|
|
43
|
+
|
|
44
|
+
```sh
|
|
45
|
+
# Read from files
|
|
46
|
+
web search < query.txt
|
|
47
|
+
web answer --provider openai < question.txt
|
|
48
|
+
web research --provider gemini < brief.md
|
|
49
|
+
web contents --provider tavily < urls.txt
|
|
50
|
+
|
|
51
|
+
# Pipe input
|
|
52
|
+
echo "What is MCP?" | web answer --provider openai
|
|
53
|
+
echo "https://example.com" | web contents --provider tavily
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Search, answer, and research read one complete input, including newlines.
|
|
57
|
+
Contents reads newline-separated URLs. Positional arguments take precedence over
|
|
58
|
+
stdin. Without arguments, a terminal reports missing input instead of waiting;
|
|
59
|
+
piped or redirected stdin is read through EOF. Empty or whitespace-only stdin is
|
|
60
|
+
an input error. An explicit `-` still reads stdin, including from a terminal, but
|
|
61
|
+
cannot be mixed with positional input. Help never reads stdin.
|
|
62
|
+
|
|
63
|
+
None of these commands accepts repeated `--query`, `--output`, or `--raw` flags.
|
|
64
|
+
|
|
65
|
+
## Common controls
|
|
66
|
+
|
|
67
|
+
| Flag | Meaning |
|
|
68
|
+
| --- | --- |
|
|
69
|
+
| `--provider <id>` | Override the saved provider for this request. |
|
|
70
|
+
| `--max-results <n>` | Limit results per query; search only. |
|
|
71
|
+
| `--format text\|json` | Select the result format; text is the default, even when piped. |
|
|
72
|
+
| `--timeout <duration>` | Set the overall deadline, including credential commands and retries. |
|
|
73
|
+
| `--quiet` | Suppress progress and success notices on stderr, not errors. |
|
|
74
|
+
| `--no-color` | Disable terminal colors. |
|
|
75
|
+
| `--config <path>` | Select a configuration file. |
|
|
76
|
+
| `--cwd <path>` | Set the working directory for custom providers and option files. |
|
|
77
|
+
| `--options-json <json\|@file>` | Supply complex provider options; provider-specific flags take precedence. |
|
|
78
|
+
|
|
79
|
+
Durations require a unit: `500ms`, `30s`, `20m`, or `1h`. Ctrl-C cancels waiting
|
|
80
|
+
for stdin, credential commands, subprocesses, and provider operations.
|
|
81
|
+
Cancellation stops the caller waiting even if an SDK cannot cancel its underlying
|
|
82
|
+
request. Cancelling a remote research request does not necessarily cancel its
|
|
83
|
+
billable job.
|
|
84
|
+
|
|
85
|
+
Complex objects and options whose names collide with common flags remain
|
|
86
|
+
available through `--options-json`. Retry tuning belongs in configuration, not
|
|
87
|
+
CLI flags. See the [configuration reference](./reference.md#configuration) for
|
|
88
|
+
option precedence, deadlines, and retries.
|
|
89
|
+
|
|
90
|
+
## Provider inspection
|
|
91
|
+
|
|
92
|
+
`web providers` shows providers as rows and capabilities as columns:
|
|
93
|
+
|
|
94
|
+
- `☆` marks an unconfigured provider; `★` marks one with at least one configured
|
|
95
|
+
capability. Providers with separate credentials may still need configuration
|
|
96
|
+
for other capabilities.
|
|
97
|
+
- `✔︎` means supported, `✘︎` means unsupported, and `◉` means selected as the
|
|
98
|
+
default for that capability. Selection is independent of configuration, so an
|
|
99
|
+
unconfigured provider can still show `◉`.
|
|
100
|
+
|
|
101
|
+
The `custom` row appears only when a command is configured or a capability selects
|
|
102
|
+
it as its default. Its support checkmarks reflect configured commands. Use
|
|
103
|
+
`web providers custom` for inspection and setup guidance even before configuring
|
|
104
|
+
commands.
|
|
105
|
+
|
|
106
|
+
Configured means local settings or credential sources exist—not that credentials,
|
|
107
|
+
executables, or connectivity have been verified. Inspection and help never run
|
|
108
|
+
credential commands or initialize provider SDKs.
|
|
109
|
+
|
|
110
|
+
## Output and progress
|
|
111
|
+
|
|
112
|
+
Text remains the default when piped. Stdout contains results, not success banners
|
|
113
|
+
or execution diagnostics. Status messages go to stderr:
|
|
114
|
+
|
|
115
|
+
- `▶︎` for progress.
|
|
116
|
+
- `✔︎` for success.
|
|
117
|
+
- `✘︎` for errors.
|
|
118
|
+
- `■` for cancellation.
|
|
119
|
+
|
|
120
|
+
Errors include a stable error code and, for per-input failures, the affected input.
|
|
121
|
+
Use `--quiet` to suppress progress and success notices. Status colors follow
|
|
122
|
+
terminal detection, `NO_COLOR`, and `--no-color`; JSON never acquires terminal
|
|
123
|
+
styling. The CLI and library do not truncate results.
|
|
124
|
+
|
|
125
|
+
For remote research jobs, progress confirms submission and acceptance, then
|
|
126
|
+
reports provider status changes or elapsed time roughly every 30 seconds while
|
|
127
|
+
polling. Transient status-check failures show the retry delay and count; they do
|
|
128
|
+
not start a new research job. Opaque job IDs and duplicate completion messages
|
|
129
|
+
are omitted. One success line gives the total elapsed time; the report itself
|
|
130
|
+
goes to stdout. These updates describe provider status, not estimated completion
|
|
131
|
+
percentages or inferred research stages.
|
|
132
|
+
|
|
133
|
+
In text mode, failed-input diagnostics go only to stderr. JSON retains structured
|
|
134
|
+
errors in the result document as well.
|
|
135
|
+
|
|
136
|
+
## JSON results
|
|
137
|
+
|
|
138
|
+
Pipe JSON output into tools such as `jq`. For example, extract URLs from
|
|
139
|
+
successful search results:
|
|
140
|
+
|
|
141
|
+
```sh
|
|
142
|
+
web search "TypeBox" --format json | jq -r '.results[] | select(.ok) | .value.results[].url'
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
JSON is one versioned document with results in input order. Status is `ok` when
|
|
146
|
+
all inputs succeed and `partial` otherwise:
|
|
147
|
+
|
|
148
|
+
```json
|
|
149
|
+
{
|
|
150
|
+
"schemaVersion": 1,
|
|
151
|
+
"capability": "search",
|
|
152
|
+
"provider": "brave",
|
|
153
|
+
"status": "partial",
|
|
154
|
+
"results": [
|
|
155
|
+
{ "input": "first query", "ok": true, "value": { "results": [] } },
|
|
156
|
+
{
|
|
157
|
+
"input": "second query",
|
|
158
|
+
"ok": false,
|
|
159
|
+
"error": { "code": "TIMEOUT", "message": "Operation exceeded its deadline." }
|
|
160
|
+
}
|
|
161
|
+
]
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
A result has either `ok: true` and `value`, or `ok: false` and a structured
|
|
166
|
+
`error`. Partial batches retain completed successes, including when another input
|
|
167
|
+
times out or is cancelled. A contents result's `input` is the requested URL;
|
|
168
|
+
`value.url` is the final URL when the provider reports it.
|
|
169
|
+
|
|
170
|
+
## Exit codes
|
|
171
|
+
|
|
172
|
+
| Code | Meaning |
|
|
173
|
+
| --- | --- |
|
|
174
|
+
| `0` | Success or help. |
|
|
175
|
+
| `1` | Provider failure, partial result, or timeout. |
|
|
176
|
+
| `2` | Invalid input or configuration. |
|
|
177
|
+
| `130` | Cancellation. |
|
package/docs/provider.md
ADDED
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
# Provider guide
|
|
2
|
+
|
|
3
|
+
Choose a provider for each capability, then supply its credentials. Save your
|
|
4
|
+
choices with `web config default`, or select a provider for one request with
|
|
5
|
+
`--provider`.
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
web providers
|
|
9
|
+
web providers brave
|
|
10
|
+
web search --provider brave --help
|
|
11
|
+
web config default search brave
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
`web providers <id>` shows setup guidance and supported capabilities. Configured
|
|
15
|
+
means local settings or credential sources exist—not that credentials or
|
|
16
|
+
connectivity have been verified. Inspection and help don't run credential commands
|
|
17
|
+
or make provider requests.
|
|
18
|
+
|
|
19
|
+
Use `web <capability> --provider <id> --help` for the full list of supported
|
|
20
|
+
options. To save options or read credentials from a password manager, see the
|
|
21
|
+
[configuration reference](./reference.md#configuration).
|
|
22
|
+
|
|
23
|
+
## Brave
|
|
24
|
+
|
|
25
|
+
Supports search, answers, and research. Set `BRAVE_SEARCH_API_KEY` for search and
|
|
26
|
+
`BRAVE_ANSWERS_API_KEY` for answers and research. The keys are separate; configuring
|
|
27
|
+
one doesn't configure the other capabilities.
|
|
28
|
+
|
|
29
|
+
```sh
|
|
30
|
+
web search "Node.js release notes" --provider brave
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Cloudflare
|
|
34
|
+
|
|
35
|
+
Supports page extraction through Cloudflare Browser Rendering. Set both
|
|
36
|
+
`CLOUDFLARE_API_TOKEN` and `CLOUDFLARE_ACCOUNT_ID`.
|
|
37
|
+
|
|
38
|
+
```sh
|
|
39
|
+
web contents https://example.com --provider cloudflare
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Custom
|
|
43
|
+
|
|
44
|
+
Connect your own command for any of the four capabilities. Configure
|
|
45
|
+
`providers.custom.commands.<capability>.argv`, optionally with `cwd` and
|
|
46
|
+
credential-source `env` entries. Only configured commands are available.
|
|
47
|
+
|
|
48
|
+
The process receives one JSON request:
|
|
49
|
+
|
|
50
|
+
```json
|
|
51
|
+
{
|
|
52
|
+
"schemaVersion": 1,
|
|
53
|
+
"capability": "search",
|
|
54
|
+
"input": { "query": "example", "maxResults": 5 },
|
|
55
|
+
"options": {},
|
|
56
|
+
"cwd": "/working/directory"
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Write one normalized result object to stdout and newline-delimited progress to
|
|
61
|
+
stderr. A nonzero exit signals failure. Contents answers must include a zero-based
|
|
62
|
+
`inputIndex` relative to the process request; `url` separately represents the final
|
|
63
|
+
URL. Errors are structured `{ "code": "PROVIDER_FAILURE", "message": "..." }`
|
|
64
|
+
objects. See the [custom-provider example](../examples/custom/README.md) for a
|
|
65
|
+
working command and the complete request/response contract.
|
|
66
|
+
|
|
67
|
+
## Exa
|
|
68
|
+
|
|
69
|
+
Supports search, page extraction, answers, and research. Set `EXA_API_KEY`.
|
|
70
|
+
Research returns a synthesized report with source links.
|
|
71
|
+
|
|
72
|
+
```sh
|
|
73
|
+
web search "Node.js release notes" --provider exa
|
|
74
|
+
web research "Compare databases for an analytics service" --provider exa --timeout 20m
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Firecrawl
|
|
78
|
+
|
|
79
|
+
Supports search, page extraction, and page-scoped answers. Set `FIRECRAWL_API_KEY`
|
|
80
|
+
for the hosted service. A self-hosted `providers.firecrawl.baseUrl` can work
|
|
81
|
+
without an API key.
|
|
82
|
+
|
|
83
|
+
Answers require a page URL, supplied through provider defaults or `--url`:
|
|
84
|
+
|
|
85
|
+
```sh
|
|
86
|
+
web contents https://example.com --provider firecrawl
|
|
87
|
+
web answer "What does this page explain?" --provider firecrawl --url https://example.com
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Gemini
|
|
91
|
+
|
|
92
|
+
Supports grounded answers and research, not standalone search. Set
|
|
93
|
+
`GOOGLE_API_KEY`. Google's Search tool runs inside a model interaction; Webfox
|
|
94
|
+
does not discard the generated answer and present its sources as ordinary search
|
|
95
|
+
results.
|
|
96
|
+
|
|
97
|
+
Answers default to `gemini-3.8-flash`. Override the model with
|
|
98
|
+
`providers.gemini.options.answer.model` or the answer command's `--model` flag.
|
|
99
|
+
Research uses `deep-research-preview-04-2026`, Google's standard
|
|
100
|
+
[Deep Research agent](https://ai.google.dev/gemini-api/docs/deep-research).
|
|
101
|
+
The research agent is fixed; answer model settings don't affect it.
|
|
102
|
+
|
|
103
|
+
If you previously selected Gemini for search, choose a search-capable provider
|
|
104
|
+
and remove `providers.gemini.options.search` from your configuration.
|
|
105
|
+
|
|
106
|
+
## Linkup
|
|
107
|
+
|
|
108
|
+
Supports search, page extraction, and research. Set `LINKUP_API_KEY`.
|
|
109
|
+
|
|
110
|
+
```sh
|
|
111
|
+
web search "Node.js release notes" --provider linkup
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Ollama
|
|
115
|
+
|
|
116
|
+
Supports search and page extraction through **hosted web APIs** at
|
|
117
|
+
`https://ollama.com`, not through the local Ollama model server. Set
|
|
118
|
+
`OLLAMA_API_KEY` from your Ollama account; no model download or local daemon is
|
|
119
|
+
required.
|
|
120
|
+
|
|
121
|
+
```sh
|
|
122
|
+
web search "Node.js streams documentation" --provider ollama --max-results 5
|
|
123
|
+
web contents https://example.com --provider ollama
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Search supports up to 10 results. The `contents` capability uses Ollama's web
|
|
127
|
+
fetch endpoint. `providers.ollama.baseUrl` can point to a compatible proxy; it
|
|
128
|
+
does not turn the local inference API into a web search service.
|
|
129
|
+
|
|
130
|
+
## OpenAI
|
|
131
|
+
|
|
132
|
+
Supports search, grounded answers, and research. Set `OPENAI_API_KEY`.
|
|
133
|
+
|
|
134
|
+
```sh
|
|
135
|
+
web answer "What is MCP?" --provider openai --model gpt-6-astra
|
|
136
|
+
web search --provider openai --help
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## Parallel
|
|
140
|
+
|
|
141
|
+
Supports search and page extraction. Set `PARALLEL_API_KEY`.
|
|
142
|
+
|
|
143
|
+
```sh
|
|
144
|
+
web search "Node.js release notes" --provider parallel
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
## Perplexity
|
|
148
|
+
|
|
149
|
+
Supports search, grounded answers, and research. Set `PERPLEXITY_API_KEY`.
|
|
150
|
+
|
|
151
|
+
```sh
|
|
152
|
+
web answer "What is MCP?" --provider perplexity
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
## Serper
|
|
156
|
+
|
|
157
|
+
Supports search. Set `SERPER_API_KEY`.
|
|
158
|
+
|
|
159
|
+
```sh
|
|
160
|
+
web search "Node.js release notes" --provider serper
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## Tavily
|
|
164
|
+
|
|
165
|
+
Supports search and page extraction. Set `TAVILY_API_KEY`.
|
|
166
|
+
|
|
167
|
+
```sh
|
|
168
|
+
web contents https://example.com --provider tavily
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## Valyu
|
|
172
|
+
|
|
173
|
+
Supports search, page extraction, answers, and research. Set `VALYU_API_KEY`.
|
|
174
|
+
|
|
175
|
+
```sh
|
|
176
|
+
web search "Node.js release notes" --provider valyu
|
|
177
|
+
```
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
# Webfox reference
|
|
2
|
+
|
|
3
|
+
This reference covers advanced configuration and the TypeScript API. For everyday
|
|
4
|
+
commands, start with the [README](../README.md). See the
|
|
5
|
+
[provider guide](./provider.md) for setup and provider-specific behavior, or the
|
|
6
|
+
[CLI reference](./cli-experience.md) for scripting and output contracts.
|
|
7
|
+
|
|
8
|
+
## Configuration
|
|
9
|
+
|
|
10
|
+
### File selection and validation
|
|
11
|
+
|
|
12
|
+
Configuration paths resolve in this order:
|
|
13
|
+
|
|
14
|
+
1. `--config` or the library's `configPath`.
|
|
15
|
+
2. `WEBFOX_CONFIG`.
|
|
16
|
+
3. `%APPDATA%\webfox\config.yaml` on Windows, when `APPDATA` is set.
|
|
17
|
+
4. `$XDG_CONFIG_HOME/webfox/config.yaml`.
|
|
18
|
+
5. `~/.config/webfox/config.yaml`.
|
|
19
|
+
|
|
20
|
+
A missing default file means no saved settings. An explicitly selected missing
|
|
21
|
+
file is an error; `web config default` can create it. The setter preserves
|
|
22
|
+
unrelated settings and comments and atomically replaces the file with owner-only
|
|
23
|
+
permissions. `web config show` emits redacted YAML, hiding literal credentials
|
|
24
|
+
and credential commands. `web config validate` checks configuration and provider
|
|
25
|
+
option schemas without resolving credentials or making requests.
|
|
26
|
+
|
|
27
|
+
Use YAML 1.2 with string mapping keys and finite numbers. Duplicate keys,
|
|
28
|
+
multiple documents, aliases, explicit tags, and unknown configuration fields are
|
|
29
|
+
rejected. Empty files are valid and mean no saved settings. The published JSON
|
|
30
|
+
Schema supports validation and editor completion and is available as
|
|
31
|
+
`webfox/config.schema.json`.
|
|
32
|
+
|
|
33
|
+
JSON syntax is also valid YAML. To use a JSON configuration file, select it
|
|
34
|
+
explicitly with `WEBFOX_CONFIG` or `--config`.
|
|
35
|
+
|
|
36
|
+
See the [example configuration](../example-config.yaml).
|
|
37
|
+
|
|
38
|
+
### Defaults and provider options
|
|
39
|
+
|
|
40
|
+
Capability defaults contain only provider selection and portable settings
|
|
41
|
+
(currently search's `maxResults`). Provider-specific options belong exclusively
|
|
42
|
+
under that provider:
|
|
43
|
+
|
|
44
|
+
```yaml
|
|
45
|
+
defaults:
|
|
46
|
+
search:
|
|
47
|
+
provider: brave
|
|
48
|
+
maxResults: 5
|
|
49
|
+
answer:
|
|
50
|
+
provider: openai
|
|
51
|
+
execution:
|
|
52
|
+
timeoutMs: 30000
|
|
53
|
+
researchTimeoutMs: 1800000
|
|
54
|
+
retries: 1
|
|
55
|
+
retryDelayMs: 2000
|
|
56
|
+
concurrency: 4
|
|
57
|
+
providers:
|
|
58
|
+
brave:
|
|
59
|
+
options:
|
|
60
|
+
search:
|
|
61
|
+
mode: news
|
|
62
|
+
openai:
|
|
63
|
+
credentials:
|
|
64
|
+
api:
|
|
65
|
+
command: [op, read, "op://vault/openai/api-key"]
|
|
66
|
+
options:
|
|
67
|
+
answer:
|
|
68
|
+
model: gpt-6-astra
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Options have one precedence order, from lowest to highest:
|
|
72
|
+
|
|
73
|
+
1. Provider defaults.
|
|
74
|
+
2. `providers.<id>.options.<capability>`.
|
|
75
|
+
3. Request options, or CLI `--options-json`.
|
|
76
|
+
4. Provider-specific CLI flags.
|
|
77
|
+
|
|
78
|
+
Switching providers never carries the previous provider's options into a request.
|
|
79
|
+
Defaults and overrides can be incomplete; required fields are checked after
|
|
80
|
+
merging. For example, Firecrawl answers need a `url` supplied in defaults or
|
|
81
|
+
with `--url`.
|
|
82
|
+
|
|
83
|
+
### Credentials
|
|
84
|
+
|
|
85
|
+
Each credential source has exactly one form:
|
|
86
|
+
|
|
87
|
+
```yaml
|
|
88
|
+
{ env: OPENAI_API_KEY }
|
|
89
|
+
{ command: [program, argument] }
|
|
90
|
+
{ value: "literal-secret" }
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Standard environment references work without a provider section. `web providers
|
|
94
|
+
<id>` lists credential names. See the [provider guide](./provider.md) for each
|
|
95
|
+
provider's keys and setup requirements.
|
|
96
|
+
|
|
97
|
+
Credential commands run asynchronously as argument arrays, never through a shell.
|
|
98
|
+
They inherit the client's environment and working directory and obey its request
|
|
99
|
+
signal. Successful outputs are cached per client, not globally. Overriding one
|
|
100
|
+
credential preserves the provider's other standard references.
|
|
101
|
+
|
|
102
|
+
Resolved credentials are redacted from results, progress, and public errors
|
|
103
|
+
before they reach callers. Secret-bearing metadata fields are also redacted.
|
|
104
|
+
This policy is not a sandbox for untrusted adapters or commands.
|
|
105
|
+
|
|
106
|
+
### Timeouts, retries, and cancellation
|
|
107
|
+
|
|
108
|
+
Defaults are 30 seconds for ordinary operations, 30 minutes for research, four
|
|
109
|
+
concurrent inputs, and no retries. Retry backoff starts at two seconds and grows
|
|
110
|
+
up to 30 seconds within the same overall deadline. The deadline includes
|
|
111
|
+
credential commands, provider operations, and retries.
|
|
112
|
+
|
|
113
|
+
Only transient failures on operations the adapter marks retry-safe are retried.
|
|
114
|
+
Research job creation is never blindly retried; polling applies the configured
|
|
115
|
+
retry count and backoff without creating another job. URL operations are
|
|
116
|
+
scheduled separately so completed pages survive another page's failure or
|
|
117
|
+
timeout.
|
|
118
|
+
|
|
119
|
+
Cancellation stops the caller waiting even if an SDK cannot cancel its underlying
|
|
120
|
+
request. Cancelling a remote research request does not necessarily cancel its
|
|
121
|
+
billable job.
|
|
122
|
+
|
|
123
|
+
## TypeScript library
|
|
124
|
+
|
|
125
|
+
```ts
|
|
126
|
+
import { createWebfox } from "webfox";
|
|
127
|
+
|
|
128
|
+
const web = createWebfox();
|
|
129
|
+
const document = await web.search({
|
|
130
|
+
provider: "openai",
|
|
131
|
+
queries: ["TypeBox validation", "Node.js AbortSignal"],
|
|
132
|
+
maxResults: 5,
|
|
133
|
+
options: { searchContextSize: "high" },
|
|
134
|
+
timeoutMs: 30_000,
|
|
135
|
+
onProgress: ({ message }) => console.error(message),
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
for (const result of document.results) {
|
|
139
|
+
if (result.ok) console.log(result.value.results);
|
|
140
|
+
else console.error(result.error.code, result.error.message);
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
`createWebfox({ config?, configPath?, cwd?, env? })` snapshots configuration and
|
|
145
|
+
environment for one client. It exposes:
|
|
146
|
+
|
|
147
|
+
- `search({ queries, maxResults?, ...controls })`.
|
|
148
|
+
- `contents({ urls, ...controls })`.
|
|
149
|
+
- `answer({ queries, ...controls })`.
|
|
150
|
+
- `research({ input, ...controls })`.
|
|
151
|
+
- `inspectCapability(capability, provider?)`: selection, configuration status,
|
|
152
|
+
provider option-override schema, and effective non-secret defaults.
|
|
153
|
+
- `listProviders()` and `getProvider(id)`: supported/configured capabilities and
|
|
154
|
+
saved selections.
|
|
155
|
+
|
|
156
|
+
Request controls are `provider`, `options`, `timeoutMs`, `signal`, and
|
|
157
|
+
`onProgress`. Planning errors throw `WebfoxError`; per-input execution failures
|
|
158
|
+
remain in the document. Results use the same
|
|
159
|
+
[document contract as CLI JSON](./cli-experience.md#json-results), without
|
|
160
|
+
truncation. Provider registration is deliberately not public; use a
|
|
161
|
+
[custom provider command](./provider.md#custom) to connect another backend.
|
|
162
|
+
|
|
163
|
+
For all capabilities, `onProgress` includes per-input lifecycle events with
|
|
164
|
+
`inputIndex`, `input`, and `state` (`queued`, `running`, `done`, `failed`, or
|
|
165
|
+
`cancelled`). Indexes refer to the original input order, including duplicate
|
|
166
|
+
inputs. Provider progress messages may omit these fields.
|
|
167
|
+
|
|
168
|
+
## pi extension behavior
|
|
169
|
+
|
|
170
|
+
Webfox exposes `web_search`, `web_contents`, `web_answer`, and `web_research`
|
|
171
|
+
for capabilities with an explicitly configured default provider. Each tool's
|
|
172
|
+
parameter schema is built dynamically from that provider: the model sees its
|
|
173
|
+
supported options rather than parameters for every backend. Unsupported
|
|
174
|
+
parameters are rejected with their exact paths and, when unambiguous, a suggested
|
|
175
|
+
valid location.
|
|
176
|
+
|
|
177
|
+
Restart pi after changing configuration to refresh the tool schemas. The
|
|
178
|
+
extension forwards cancellation and progress, marks partial results as errors,
|
|
179
|
+
and truncates tool output at 2,000 lines or 50 KiB, with full results saved to a
|
|
180
|
+
temporary file. It needs no globally installed `web` command and starts no
|
|
181
|
+
background research jobs.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
$schema: https://unpkg.com/webfox@3.5.1/dist/config.schema.json
|
|
2
|
+
defaults:
|
|
3
|
+
search:
|
|
4
|
+
provider: brave
|
|
5
|
+
maxResults: 5
|
|
6
|
+
contents:
|
|
7
|
+
provider: tavily
|
|
8
|
+
answer:
|
|
9
|
+
provider: openai
|
|
10
|
+
research:
|
|
11
|
+
provider: gemini
|
|
12
|
+
execution:
|
|
13
|
+
timeoutMs: 30000
|
|
14
|
+
retries: 1
|
|
15
|
+
retryDelayMs: 2000
|
|
16
|
+
researchTimeoutMs: 1800000
|
|
17
|
+
providers:
|
|
18
|
+
brave:
|
|
19
|
+
credentials:
|
|
20
|
+
search:
|
|
21
|
+
env: BRAVE_SEARCH_API_KEY
|
|
22
|
+
tavily:
|
|
23
|
+
credentials:
|
|
24
|
+
api:
|
|
25
|
+
env: TAVILY_API_KEY
|
|
26
|
+
openai:
|
|
27
|
+
credentials:
|
|
28
|
+
api:
|
|
29
|
+
env: OPENAI_API_KEY
|
|
30
|
+
options:
|
|
31
|
+
answer:
|
|
32
|
+
model: gpt-6-astra
|
|
33
|
+
gemini:
|
|
34
|
+
credentials:
|
|
35
|
+
api:
|
|
36
|
+
env: GOOGLE_API_KEY
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Custom provider example
|
|
2
|
+
|
|
3
|
+
`provider.mjs` implements all four capabilities without network access. Run the
|
|
4
|
+
example from the repository root using the included `webfox.json`:
|
|
5
|
+
|
|
6
|
+
```sh
|
|
7
|
+
web search "example query" --config examples/custom/webfox.json
|
|
8
|
+
web contents https://example.com --config examples/custom/webfox.json --format json
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
The configuration defines explicit custom commands and saved defaults. In your
|
|
12
|
+
own setup, use absolute command paths or set the command’s `cwd`.
|
|
13
|
+
|
|
14
|
+
## Process contract
|
|
15
|
+
|
|
16
|
+
Each invocation receives one JSON request on stdin, writes one JSON object to
|
|
17
|
+
stdout, and sends newline-delimited progress to stderr. A nonzero exit signals
|
|
18
|
+
failure. The runtime bounds process output and terminates the process group on
|
|
19
|
+
cancellation or timeout (the direct child on Windows).
|
|
20
|
+
|
|
21
|
+
```json
|
|
22
|
+
{
|
|
23
|
+
"schemaVersion": 1,
|
|
24
|
+
"capability": "search",
|
|
25
|
+
"input": { "query": "example", "maxResults": 5 },
|
|
26
|
+
"options": {},
|
|
27
|
+
"cwd": "/working/directory"
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Payloads and responses:
|
|
32
|
+
|
|
33
|
+
| Capability | Input | Response |
|
|
34
|
+
| --- | --- | --- |
|
|
35
|
+
| Search | `{ "query": "...", "maxResults": 5 }` | `{ "results": [{ "title": "...", "url": "https://...", "snippet": "..." }] }` |
|
|
36
|
+
| Contents | `{ "urls": ["https://..."] }` | `{ "answers": [{ "inputIndex": 0, "url": "https://...", "content": "..." }] }` |
|
|
37
|
+
| Answer | `{ "query": "..." }` | `{ "text": "..." }` |
|
|
38
|
+
| Research | `{ "input": "..." }` | `{ "text": "..." }` |
|
|
39
|
+
|
|
40
|
+
Contents answers must cover every request index exactly once. `inputIndex`
|
|
41
|
+
associates a response with the requested URL; `url` can hold a redirected URL.
|
|
42
|
+
A failed page uses a structured error instead of content:
|
|
43
|
+
|
|
44
|
+
```json
|
|
45
|
+
{
|
|
46
|
+
"inputIndex": 0,
|
|
47
|
+
"url": "https://example.com",
|
|
48
|
+
"error": { "code": "PROVIDER_FAILURE", "message": "Extraction failed." }
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
The runtime currently schedules one URL per invocation. Treat indices as local
|
|
53
|
+
to the supplied request, not the entire user batch.
|
|
54
|
+
|
|
55
|
+
Replace the deterministic branches with your own integrations. Credentials for
|
|
56
|
+
child processes go in the command’s `env` map as `{ "env": "NAME" }`,
|
|
57
|
+
`{ "command": ["program", "arg"] }`, or `{ "value": "..." }` sources.
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
let body = "";
|
|
2
|
+
for await (const chunk of process.stdin) body += chunk;
|
|
3
|
+
|
|
4
|
+
const request = JSON.parse(body);
|
|
5
|
+
if (request.schemaVersion !== 1) {
|
|
6
|
+
process.stderr.write("unsupported schemaVersion\n");
|
|
7
|
+
process.exit(2);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
process.stderr.write(`running custom ${request.capability}\n`);
|
|
11
|
+
|
|
12
|
+
switch (request.capability) {
|
|
13
|
+
case "search":
|
|
14
|
+
process.stdout.write(
|
|
15
|
+
JSON.stringify({
|
|
16
|
+
results: [
|
|
17
|
+
{
|
|
18
|
+
title: `Example result for ${request.input.query}`,
|
|
19
|
+
url: "https://example.com/",
|
|
20
|
+
snippet: "Replace this branch with your search integration.",
|
|
21
|
+
},
|
|
22
|
+
],
|
|
23
|
+
}),
|
|
24
|
+
);
|
|
25
|
+
break;
|
|
26
|
+
case "contents":
|
|
27
|
+
process.stdout.write(
|
|
28
|
+
JSON.stringify({
|
|
29
|
+
answers: request.input.urls.map((url, inputIndex) => ({
|
|
30
|
+
inputIndex,
|
|
31
|
+
url,
|
|
32
|
+
content: `Example contents for ${url}`,
|
|
33
|
+
})),
|
|
34
|
+
}),
|
|
35
|
+
);
|
|
36
|
+
break;
|
|
37
|
+
case "answer":
|
|
38
|
+
process.stdout.write(
|
|
39
|
+
JSON.stringify({
|
|
40
|
+
text: `Example answer for ${request.input.query}`,
|
|
41
|
+
}),
|
|
42
|
+
);
|
|
43
|
+
break;
|
|
44
|
+
case "research":
|
|
45
|
+
process.stdout.write(
|
|
46
|
+
JSON.stringify({
|
|
47
|
+
text: `Example research report for ${request.input.input}`,
|
|
48
|
+
}),
|
|
49
|
+
);
|
|
50
|
+
break;
|
|
51
|
+
default:
|
|
52
|
+
process.stderr.write("unsupported capability\n");
|
|
53
|
+
process.exit(2);
|
|
54
|
+
}
|