webfox 4.10.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.
- package/README.md +2 -12
- package/dist/{adapter-UIFBJKKF.js → adapter-44ZBIK47.js} +4 -6
- package/dist/{adapter-HTMXAJTU.js → adapter-57MELLYI.js} +2 -8
- package/dist/{adapter-VMMS4YQG.js → adapter-BZO5UEI6.js} +3 -15
- package/dist/{adapter-OK2PTP6R.js → adapter-D4EXZEDL.js} +16 -48
- package/dist/{adapter-G3I7JEO5.js → adapter-DJCTEEOA.js} +3 -5
- package/dist/{adapter-764OQFKY.js → adapter-DLNMW34W.js} +8 -35
- package/dist/{adapter-HRI5ZMGK.js → adapter-GFXYSHKP.js} +9 -43
- package/dist/{adapter-2UVAARTV.js → adapter-GJOUFE2U.js} +1 -1
- package/dist/{adapter-C2VZHFUB.js → adapter-MZ7USB6Q.js} +3 -4
- package/dist/adapter-ODDFBGJG.js +167 -0
- package/dist/{adapter-K6AMSUCR.js → adapter-QQZFHUOP.js} +14 -37
- package/dist/{adapter-AUYLTDPM.js → adapter-RR55EZAW.js} +1 -1
- package/dist/{adapter-JJSMYZXG.js → adapter-SZMVKAMC.js} +1 -1
- package/dist/{adapter-6EZAIE65.js → adapter-VXT4C6RZ.js} +16 -66
- package/dist/{adapter-L6BFKWGX.js → adapter-WXEVTCM3.js} +7 -14
- package/dist/{adapter-ZYDUANQL.js → adapter-XSQX3GAI.js} +13 -5
- package/dist/{adapter-EIDSGLOP.js → adapter-XU2APKPC.js} +3 -3
- package/dist/{adapter-A5WYGGZI.js → adapter-YVZ4YBK5.js} +8 -16
- package/dist/chunk-6RQGO727.js +71 -0
- package/dist/{chunk-TGULKHB5.js → chunk-KMUCUJVN.js} +3 -3
- package/dist/{chunk-EF4VMDZL.js → chunk-LDVDVA4Z.js} +1 -4
- package/dist/{chunk-57OOEOXI.js → chunk-NENL6L6N.js} +1 -0
- package/dist/{chunk-5FP7KNMC.js → chunk-PVNWACMT.js} +132 -18
- package/dist/{chunk-YZXM4U2C.js → chunk-TYJ6RHKB.js} +10 -0
- package/dist/{chunk-3WBE6UEW.js → chunk-YILOS4E7.js} +23 -9
- package/dist/cli.js +5 -5
- package/dist/config.schema.json +187 -0
- package/dist/contents.d.ts +5 -0
- package/dist/document-schema.d.ts +17 -5
- package/dist/domain.d.ts +14 -2
- package/dist/durable.js +5 -5
- package/dist/index.js +4 -4
- package/dist/pi.js +33 -14
- package/dist/providers/contract.d.ts +11 -1
- package/dist/providers/registry.d.ts +1 -0
- package/dist/providers/sofya/adapter.d.ts +8 -0
- package/dist/providers/sofya/definition.d.ts +1 -0
- package/dist/providers/sofya/types.d.ts +4 -0
- package/dist/render.d.ts +8 -2
- package/docs/provider.md +27 -0
- package/examples/custom/README.md +9 -3
- package/package.json +1 -1
- package/dist/chunk-BTWECET5.js +0 -31
|
@@ -8,14 +8,14 @@ export declare const DOCUMENT_SCHEMAS: {
|
|
|
8
8
|
readonly search: Type.TObject<{
|
|
9
9
|
schemaVersion: Type.TLiteral<1>;
|
|
10
10
|
capability: Type.TLiteral<"search">;
|
|
11
|
-
provider: Type.TEnum<["brave", "cloudflare", "custom", "exa", "firecrawl", "gemini", "keenable", "linkup", "ollama", "openai", "parallel", "perplexity", "serpbase", "serper", "tavily", "valyu", "youcom"]>;
|
|
11
|
+
provider: Type.TEnum<["brave", "cloudflare", "custom", "exa", "firecrawl", "gemini", "keenable", "linkup", "ollama", "openai", "parallel", "perplexity", "serpbase", "serper", "sofya", "tavily", "valyu", "youcom"]>;
|
|
12
12
|
status: Type.TEnum<["ok", "partial"]>;
|
|
13
13
|
results: Type.TArray<Type.TUnion<[Type.TObject<{
|
|
14
14
|
input: Type.TString;
|
|
15
15
|
ok: Type.TLiteral<true>;
|
|
16
16
|
value: Type.TObject<{
|
|
17
17
|
results: Type.TArray<Type.TObject<{
|
|
18
|
-
title: Type.TString
|
|
18
|
+
title: Type.TOptional<Type.TString>;
|
|
19
19
|
url: Type.TString;
|
|
20
20
|
snippet: Type.TString;
|
|
21
21
|
score: Type.TOptional<Type.TNumber>;
|
|
@@ -35,7 +35,7 @@ export declare const DOCUMENT_SCHEMAS: {
|
|
|
35
35
|
readonly contents: Type.TObject<{
|
|
36
36
|
schemaVersion: Type.TLiteral<1>;
|
|
37
37
|
capability: Type.TLiteral<"contents">;
|
|
38
|
-
provider: Type.TEnum<["brave", "cloudflare", "custom", "exa", "firecrawl", "gemini", "keenable", "linkup", "ollama", "openai", "parallel", "perplexity", "serpbase", "serper", "tavily", "valyu", "youcom"]>;
|
|
38
|
+
provider: Type.TEnum<["brave", "cloudflare", "custom", "exa", "firecrawl", "gemini", "keenable", "linkup", "ollama", "openai", "parallel", "perplexity", "serpbase", "serper", "sofya", "tavily", "valyu", "youcom"]>;
|
|
39
39
|
status: Type.TEnum<["ok", "partial"]>;
|
|
40
40
|
results: Type.TArray<Type.TUnion<[Type.TObject<{
|
|
41
41
|
input: Type.TString;
|
|
@@ -59,13 +59,19 @@ export declare const DOCUMENT_SCHEMAS: {
|
|
|
59
59
|
readonly answer: Type.TObject<{
|
|
60
60
|
schemaVersion: Type.TLiteral<1>;
|
|
61
61
|
capability: Type.TLiteral<"answer">;
|
|
62
|
-
provider: Type.TEnum<["brave", "cloudflare", "custom", "exa", "firecrawl", "gemini", "keenable", "linkup", "ollama", "openai", "parallel", "perplexity", "serpbase", "serper", "tavily", "valyu", "youcom"]>;
|
|
62
|
+
provider: Type.TEnum<["brave", "cloudflare", "custom", "exa", "firecrawl", "gemini", "keenable", "linkup", "ollama", "openai", "parallel", "perplexity", "serpbase", "serper", "sofya", "tavily", "valyu", "youcom"]>;
|
|
63
63
|
status: Type.TEnum<["ok", "partial"]>;
|
|
64
64
|
results: Type.TArray<Type.TUnion<[Type.TObject<{
|
|
65
65
|
input: Type.TString;
|
|
66
66
|
ok: Type.TLiteral<true>;
|
|
67
67
|
value: Type.TObject<{
|
|
68
68
|
text: Type.TString;
|
|
69
|
+
sources: Type.TOptional<Type.TArray<Type.TUnion<[Type.TObject<{
|
|
70
|
+
url: Type.TString;
|
|
71
|
+
title: Type.TOptional<Type.TString>;
|
|
72
|
+
}>, Type.TObject<{
|
|
73
|
+
title: Type.TString;
|
|
74
|
+
}>]>>>;
|
|
69
75
|
itemCount: Type.TOptional<Type.TInteger>;
|
|
70
76
|
metadata: Type.TOptional<Type.TRecord<"^.*$", Type.TUnknown>>;
|
|
71
77
|
}>;
|
|
@@ -82,13 +88,19 @@ export declare const DOCUMENT_SCHEMAS: {
|
|
|
82
88
|
readonly research: Type.TObject<{
|
|
83
89
|
schemaVersion: Type.TLiteral<1>;
|
|
84
90
|
capability: Type.TLiteral<"research">;
|
|
85
|
-
provider: Type.TEnum<["brave", "cloudflare", "custom", "exa", "firecrawl", "gemini", "keenable", "linkup", "ollama", "openai", "parallel", "perplexity", "serpbase", "serper", "tavily", "valyu", "youcom"]>;
|
|
91
|
+
provider: Type.TEnum<["brave", "cloudflare", "custom", "exa", "firecrawl", "gemini", "keenable", "linkup", "ollama", "openai", "parallel", "perplexity", "serpbase", "serper", "sofya", "tavily", "valyu", "youcom"]>;
|
|
86
92
|
status: Type.TEnum<["ok", "partial"]>;
|
|
87
93
|
results: Type.TArray<Type.TUnion<[Type.TObject<{
|
|
88
94
|
input: Type.TString;
|
|
89
95
|
ok: Type.TLiteral<true>;
|
|
90
96
|
value: Type.TObject<{
|
|
91
97
|
text: Type.TString;
|
|
98
|
+
sources: Type.TOptional<Type.TArray<Type.TUnion<[Type.TObject<{
|
|
99
|
+
url: Type.TString;
|
|
100
|
+
title: Type.TOptional<Type.TString>;
|
|
101
|
+
}>, Type.TObject<{
|
|
102
|
+
title: Type.TString;
|
|
103
|
+
}>]>>>;
|
|
92
104
|
itemCount: Type.TOptional<Type.TInteger>;
|
|
93
105
|
metadata: Type.TOptional<Type.TRecord<"^.*$", Type.TUnknown>>;
|
|
94
106
|
}>;
|
package/dist/domain.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export declare const CAPABILITIES: readonly ["search", "contents", "answer", "research"];
|
|
2
2
|
export type Capability = (typeof CAPABILITIES)[number];
|
|
3
|
-
export declare const PROVIDER_IDS: readonly ["brave", "cloudflare", "custom", "exa", "firecrawl", "gemini", "keenable", "linkup", "ollama", "openai", "parallel", "perplexity", "serpbase", "serper", "tavily", "valyu", "youcom"];
|
|
3
|
+
export declare const PROVIDER_IDS: readonly ["brave", "cloudflare", "custom", "exa", "firecrawl", "gemini", "keenable", "linkup", "ollama", "openai", "parallel", "perplexity", "serpbase", "serper", "sofya", "tavily", "valyu", "youcom"];
|
|
4
4
|
export type ProviderId = (typeof PROVIDER_IDS)[number];
|
|
5
5
|
export declare const WEBFOX_ERROR_CODES: readonly ["INVALID_CONFIG", "INVALID_INPUT", "PROVIDER_UNAVAILABLE", "PROVIDER_FAILURE", "PARTIAL_BATCH", "TIMEOUT", "CANCELLED"];
|
|
6
6
|
export type WebfoxErrorCode = (typeof WEBFOX_ERROR_CODES)[number];
|
|
@@ -19,7 +19,8 @@ export type InputResult<T> = {
|
|
|
19
19
|
error: SerializedError;
|
|
20
20
|
};
|
|
21
21
|
export interface SearchResult {
|
|
22
|
-
title
|
|
22
|
+
/** Omitted when the provider has no title; renderers fall back to the URL. */
|
|
23
|
+
title?: string;
|
|
23
24
|
url: string;
|
|
24
25
|
snippet: string;
|
|
25
26
|
score?: number;
|
|
@@ -28,12 +29,23 @@ export interface SearchResult {
|
|
|
28
29
|
export interface ContentsAnswer {
|
|
29
30
|
/** Final fetched URL; association with the requested URL is in InputResult.input. */
|
|
30
31
|
url: string;
|
|
32
|
+
/** Omitted when the page has no content; an empty page is still a result. */
|
|
31
33
|
content?: string;
|
|
32
34
|
summary?: unknown;
|
|
33
35
|
metadata?: Record<string, unknown>;
|
|
34
36
|
}
|
|
37
|
+
/** A cited source with a nonblank URL, title, or both. */
|
|
38
|
+
export type Source = {
|
|
39
|
+
url: string;
|
|
40
|
+
title?: string;
|
|
41
|
+
} | {
|
|
42
|
+
title: string;
|
|
43
|
+
};
|
|
35
44
|
export interface TextAnswer {
|
|
45
|
+
/** Empty when the provider returned no text; an empty answer is still a result. */
|
|
36
46
|
text: string;
|
|
47
|
+
sources?: Source[];
|
|
48
|
+
/** Number of sources, derived from `sources`. */
|
|
37
49
|
itemCount?: number;
|
|
38
50
|
metadata?: Record<string, unknown>;
|
|
39
51
|
}
|
package/dist/durable.js
CHANGED
|
@@ -5,17 +5,17 @@ import {
|
|
|
5
5
|
} from "./chunk-VVOQKYOP.js";
|
|
6
6
|
import {
|
|
7
7
|
renderTextDocument
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-6RQGO727.js";
|
|
9
9
|
import {
|
|
10
10
|
createWebfox
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-YILOS4E7.js";
|
|
12
12
|
import "./chunk-WCTOYZVB.js";
|
|
13
|
-
import "./chunk-
|
|
14
|
-
import "./chunk-
|
|
13
|
+
import "./chunk-KMUCUJVN.js";
|
|
14
|
+
import "./chunk-PVNWACMT.js";
|
|
15
15
|
import "./chunk-ZVTVERW5.js";
|
|
16
16
|
import {
|
|
17
17
|
CAPABILITIES
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-NENL6L6N.js";
|
|
19
19
|
import "./chunk-U4BLULLV.js";
|
|
20
20
|
|
|
21
21
|
// src/durable.ts
|
package/dist/index.js
CHANGED
|
@@ -6,20 +6,20 @@ import {
|
|
|
6
6
|
resolveConfigPath,
|
|
7
7
|
setCapabilityDefault,
|
|
8
8
|
validateConfig
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-YILOS4E7.js";
|
|
10
10
|
import "./chunk-WCTOYZVB.js";
|
|
11
11
|
import {
|
|
12
12
|
CONFIG_SCHEMA_URL
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-KMUCUJVN.js";
|
|
14
14
|
import {
|
|
15
15
|
validateConfiguredOptions
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-PVNWACMT.js";
|
|
17
17
|
import "./chunk-ZVTVERW5.js";
|
|
18
18
|
import {
|
|
19
19
|
CAPABILITIES,
|
|
20
20
|
PROVIDER_IDS,
|
|
21
21
|
WEBFOX_ERROR_CODES
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-NENL6L6N.js";
|
|
23
23
|
import {
|
|
24
24
|
WebfoxError
|
|
25
25
|
} from "./chunk-U4BLULLV.js";
|
package/dist/pi.js
CHANGED
|
@@ -4,21 +4,22 @@ import {
|
|
|
4
4
|
webToolParameters
|
|
5
5
|
} from "./chunk-VVOQKYOP.js";
|
|
6
6
|
import {
|
|
7
|
+
emptyResultText,
|
|
7
8
|
renderTextDocument
|
|
8
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-6RQGO727.js";
|
|
9
10
|
import {
|
|
10
11
|
createWebfox,
|
|
11
12
|
resolveConfigPath
|
|
12
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-YILOS4E7.js";
|
|
13
14
|
import "./chunk-WCTOYZVB.js";
|
|
14
|
-
import "./chunk-
|
|
15
|
-
import "./chunk-
|
|
15
|
+
import "./chunk-KMUCUJVN.js";
|
|
16
|
+
import "./chunk-PVNWACMT.js";
|
|
16
17
|
import "./chunk-ZVTVERW5.js";
|
|
17
18
|
import {
|
|
18
19
|
CAPABILITIES,
|
|
19
20
|
PROVIDER_IDS,
|
|
20
21
|
WEBFOX_ERROR_CODES
|
|
21
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-NENL6L6N.js";
|
|
22
23
|
import {
|
|
23
24
|
WebfoxError
|
|
24
25
|
} from "./chunk-U4BLULLV.js";
|
|
@@ -175,7 +176,7 @@ function searchDocument(value) {
|
|
|
175
176
|
if (entry.ok === false)
|
|
176
177
|
return isRecord2(entry.error) && typeof entry.error.message === "string";
|
|
177
178
|
return entry.ok === true && isRecord2(entry.value) && Array.isArray(entry.value.results) && entry.value.results.every(
|
|
178
|
-
(result) => isRecord2(result) && typeof result.title === "string" && typeof result.url === "string" && typeof result.snippet === "string"
|
|
179
|
+
(result) => isRecord2(result) && (result.title === void 0 || typeof result.title === "string") && typeof result.url === "string" && typeof result.snippet === "string"
|
|
179
180
|
);
|
|
180
181
|
});
|
|
181
182
|
}
|
|
@@ -231,17 +232,21 @@ function renderSearchResult(details, fallback, theme) {
|
|
|
231
232
|
return;
|
|
232
233
|
}
|
|
233
234
|
if (!entry.value.results.length)
|
|
234
|
-
append(theme.fg("toolOutput", "
|
|
235
|
+
append(theme.fg("toolOutput", emptyResultText("search")));
|
|
235
236
|
entry.value.results.forEach((result, resultIndex) => {
|
|
236
237
|
if (resultIndex) lines.push("");
|
|
237
238
|
const number = `${resultIndex + 1}. `;
|
|
238
239
|
const indent = " ".repeat(number.length);
|
|
239
|
-
|
|
240
|
-
theme.fg("
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
240
|
+
if (result.title === void 0)
|
|
241
|
+
append(link(result.url, theme), theme.fg("accent", number));
|
|
242
|
+
else {
|
|
243
|
+
append(
|
|
244
|
+
theme.fg("toolOutput", plainText(result.title)),
|
|
245
|
+
theme.fg("accent", number)
|
|
246
|
+
);
|
|
247
|
+
append(link(result.url, theme), indent);
|
|
248
|
+
}
|
|
249
|
+
if (result.snippet.trim())
|
|
245
250
|
append(theme.fg("toolOutput", plainText(result.snippet)), indent);
|
|
246
251
|
});
|
|
247
252
|
});
|
|
@@ -372,7 +377,7 @@ var metadata = Type.Record(Type.String(), Type.Unknown(), {
|
|
|
372
377
|
});
|
|
373
378
|
var searchResult = Type.Object(
|
|
374
379
|
{
|
|
375
|
-
title: Type.String(),
|
|
380
|
+
title: Type.Optional(Type.String({ minLength: 1 })),
|
|
376
381
|
url: Type.String(),
|
|
377
382
|
snippet: Type.String(),
|
|
378
383
|
score: Type.Optional(Type.Number()),
|
|
@@ -392,6 +397,20 @@ var contentsAnswer = Type.Object(
|
|
|
392
397
|
var textAnswer = Type.Object(
|
|
393
398
|
{
|
|
394
399
|
text: Type.String(),
|
|
400
|
+
sources: Type.Optional(
|
|
401
|
+
Type.Array(
|
|
402
|
+
Type.Union([
|
|
403
|
+
Type.Object(
|
|
404
|
+
{
|
|
405
|
+
url: Type.String({ minLength: 1 }),
|
|
406
|
+
title: Type.Optional(Type.String({ minLength: 1 }))
|
|
407
|
+
},
|
|
408
|
+
closed
|
|
409
|
+
),
|
|
410
|
+
Type.Object({ title: Type.String({ minLength: 1 }) }, closed)
|
|
411
|
+
])
|
|
412
|
+
)
|
|
413
|
+
),
|
|
395
414
|
itemCount: Type.Optional(Type.Integer()),
|
|
396
415
|
metadata: Type.Optional(metadata)
|
|
397
416
|
},
|
|
@@ -4,10 +4,19 @@ export interface SearchResponse {
|
|
|
4
4
|
provider: ProviderId;
|
|
5
5
|
results: SearchResult[];
|
|
6
6
|
}
|
|
7
|
+
/** A provider citation; the runtime trims fields and drops blank entries. */
|
|
8
|
+
export interface SourceInput {
|
|
9
|
+
url?: string;
|
|
10
|
+
title?: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Answer and research output. Return the provider's text as-is, even when
|
|
14
|
+
* empty, and its citations as `sources`; presentation belongs to the renderer.
|
|
15
|
+
*/
|
|
7
16
|
export interface ToolOutput {
|
|
8
17
|
provider: ProviderId;
|
|
9
18
|
text: string;
|
|
10
|
-
|
|
19
|
+
sources?: SourceInput[];
|
|
11
20
|
metadata?: Record<string, unknown>;
|
|
12
21
|
}
|
|
13
22
|
export interface ResearchJob {
|
|
@@ -84,6 +93,7 @@ export interface ProviderConfigMap {
|
|
|
84
93
|
perplexity: import("./perplexity/types.js").Perplexity;
|
|
85
94
|
serpbase: import("./serpbase/types.js").SerpBase;
|
|
86
95
|
serper: import("./serper/types.js").Serper;
|
|
96
|
+
sofya: import("./sofya/types.js").Sofya;
|
|
87
97
|
tavily: import("./tavily/types.js").Tavily;
|
|
88
98
|
valyu: import("./valyu/types.js").Valyu;
|
|
89
99
|
youcom: import("./youcom/types.js").Youcom;
|
|
@@ -13,6 +13,7 @@ export declare const providers: {
|
|
|
13
13
|
readonly perplexity: import("./definition.js").ProviderDefinitionFor<"perplexity">;
|
|
14
14
|
readonly serpbase: import("./definition.js").ProviderDefinitionFor<"serpbase">;
|
|
15
15
|
readonly serper: import("./definition.js").ProviderDefinitionFor<"serper">;
|
|
16
|
+
readonly sofya: import("./definition.js").ProviderDefinitionFor<"sofya">;
|
|
16
17
|
readonly tavily: import("./definition.js").ProviderDefinitionFor<"tavily">;
|
|
17
18
|
readonly valyu: import("./definition.js").ProviderDefinitionFor<"valyu">;
|
|
18
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">;
|
package/dist/render.d.ts
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
|
-
import type { WebDocument } from "./domain.js";
|
|
2
|
-
/**
|
|
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
|
@@ -340,6 +340,33 @@ Supports search. Set `SERPER_API_KEY`.
|
|
|
340
340
|
web search "Node.js release notes" --provider serper
|
|
341
341
|
```
|
|
342
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
|
+
|
|
343
370
|
## You.com
|
|
344
371
|
|
|
345
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.
|
|
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": [
|
package/dist/chunk-BTWECET5.js
DELETED
|
@@ -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
|
-
};
|