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
@@ -23,6 +23,7 @@
23
23
  "custom",
24
24
  "exa",
25
25
  "firecrawl",
26
+ "keenable",
26
27
  "linkup",
27
28
  "ollama",
28
29
  "openai",
@@ -30,6 +31,7 @@
30
31
  "perplexity",
31
32
  "serpbase",
32
33
  "serper",
34
+ "sofya",
33
35
  "tavily",
34
36
  "valyu",
35
37
  "youcom"
@@ -54,6 +56,7 @@
54
56
  "linkup",
55
57
  "ollama",
56
58
  "parallel",
59
+ "sofya",
57
60
  "tavily",
58
61
  "valyu"
59
62
  ]
@@ -73,6 +76,7 @@
73
76
  "gemini",
74
77
  "openai",
75
78
  "perplexity",
79
+ "sofya",
76
80
  "valyu"
77
81
  ]
78
82
  }
@@ -91,6 +95,7 @@
91
95
  "linkup",
92
96
  "openai",
93
97
  "perplexity",
98
+ "sofya",
94
99
  "valyu"
95
100
  ]
96
101
  }
@@ -2197,6 +2202,117 @@
2197
2202
  }
2198
2203
  }
2199
2204
  },
2205
+ "keenable": {
2206
+ "type": "object",
2207
+ "additionalProperties": false,
2208
+ "properties": {
2209
+ "credentials": {
2210
+ "type": "object",
2211
+ "additionalProperties": false,
2212
+ "properties": {
2213
+ "api": {
2214
+ "oneOf": [
2215
+ {
2216
+ "type": "object",
2217
+ "additionalProperties": false,
2218
+ "properties": {
2219
+ "env": {
2220
+ "type": "string",
2221
+ "minLength": 1
2222
+ }
2223
+ },
2224
+ "required": ["env"]
2225
+ },
2226
+ {
2227
+ "type": "object",
2228
+ "additionalProperties": false,
2229
+ "properties": {
2230
+ "value": {
2231
+ "type": "string",
2232
+ "minLength": 1
2233
+ }
2234
+ },
2235
+ "required": ["value"]
2236
+ },
2237
+ {
2238
+ "type": "object",
2239
+ "additionalProperties": false,
2240
+ "properties": {
2241
+ "command": {
2242
+ "type": "array",
2243
+ "minItems": 1,
2244
+ "items": {
2245
+ "type": "string",
2246
+ "minLength": 1
2247
+ }
2248
+ }
2249
+ },
2250
+ "required": ["command"]
2251
+ }
2252
+ ]
2253
+ }
2254
+ }
2255
+ },
2256
+ "baseUrl": {
2257
+ "type": "string",
2258
+ "minLength": 1
2259
+ },
2260
+ "options": {
2261
+ "type": "object",
2262
+ "additionalProperties": false,
2263
+ "properties": {
2264
+ "search": {
2265
+ "type": "object",
2266
+ "properties": {
2267
+ "mode": {
2268
+ "type": "string",
2269
+ "enum": ["pro", "realtime"],
2270
+ "description": "Search mode: 'pro' (default) for deeper retrieval, 'realtime' for the fastest results. Each mode is billed separately."
2271
+ },
2272
+ "site": {
2273
+ "type": "string",
2274
+ "minLength": 1,
2275
+ "description": "Restrict results to one site, e.g. 'techcrunch.com'."
2276
+ },
2277
+ "published_after": {
2278
+ "type": "string",
2279
+ "minLength": 1,
2280
+ "description": "Only pages published at or after this time. Accepts YYYY-MM-DD, an ISO 8601 timestamp, or a relative delta such as 7d, 12h, or 30min."
2281
+ },
2282
+ "published_before": {
2283
+ "type": "string",
2284
+ "minLength": 1,
2285
+ "description": "Only pages published at or before this time. Accepts YYYY-MM-DD, an ISO 8601 timestamp, or a relative delta such as 7d, 12h, or 30min."
2286
+ },
2287
+ "acquired_after": {
2288
+ "type": "string",
2289
+ "minLength": 1,
2290
+ "description": "Only pages indexed at or after this time. Accepts YYYY-MM-DD, an ISO 8601 timestamp, or a relative delta such as 7d, 12h, or 30min."
2291
+ },
2292
+ "acquired_before": {
2293
+ "type": "string",
2294
+ "minLength": 1,
2295
+ "description": "Only pages indexed at or before this time. Accepts YYYY-MM-DD, an ISO 8601 timestamp, or a relative delta such as 7d, 12h, or 30min."
2296
+ },
2297
+ "query_time": {
2298
+ "type": "string",
2299
+ "minLength": 1,
2300
+ "description": "Search the index as it stood at this date or ISO 8601 timestamp; relative time filters resolve against it."
2301
+ },
2302
+ "snippet_max_length": {
2303
+ "type": "integer",
2304
+ "minimum": 180,
2305
+ "maximum": 10000,
2306
+ "description": "Maximum characters of the excerpt per result."
2307
+ }
2308
+ },
2309
+ "description": "Keenable search options.",
2310
+ "additionalProperties": false
2311
+ }
2312
+ }
2313
+ }
2314
+ }
2315
+ },
2200
2316
  "linkup": {
2201
2317
  "type": "object",
2202
2318
  "additionalProperties": false,
@@ -3674,6 +3790,189 @@
3674
3790
  }
3675
3791
  }
3676
3792
  },
3793
+ "sofya": {
3794
+ "type": "object",
3795
+ "additionalProperties": false,
3796
+ "properties": {
3797
+ "credentials": {
3798
+ "type": "object",
3799
+ "additionalProperties": false,
3800
+ "properties": {
3801
+ "api": {
3802
+ "oneOf": [
3803
+ {
3804
+ "type": "object",
3805
+ "additionalProperties": false,
3806
+ "properties": {
3807
+ "env": {
3808
+ "type": "string",
3809
+ "minLength": 1
3810
+ }
3811
+ },
3812
+ "required": ["env"]
3813
+ },
3814
+ {
3815
+ "type": "object",
3816
+ "additionalProperties": false,
3817
+ "properties": {
3818
+ "value": {
3819
+ "type": "string",
3820
+ "minLength": 1
3821
+ }
3822
+ },
3823
+ "required": ["value"]
3824
+ },
3825
+ {
3826
+ "type": "object",
3827
+ "additionalProperties": false,
3828
+ "properties": {
3829
+ "command": {
3830
+ "type": "array",
3831
+ "minItems": 1,
3832
+ "items": {
3833
+ "type": "string",
3834
+ "minLength": 1
3835
+ }
3836
+ }
3837
+ },
3838
+ "required": ["command"]
3839
+ }
3840
+ ]
3841
+ }
3842
+ }
3843
+ },
3844
+ "baseUrl": {
3845
+ "type": "string",
3846
+ "minLength": 1
3847
+ },
3848
+ "options": {
3849
+ "type": "object",
3850
+ "additionalProperties": false,
3851
+ "properties": {
3852
+ "search": {
3853
+ "type": "object",
3854
+ "properties": {
3855
+ "search_depth": {
3856
+ "type": "string",
3857
+ "enum": ["snippets", "basic"],
3858
+ "description": "'snippets' (1 credit) returns search snippets; 'basic' (2 credits) also reads each page and returns its text in metadata.content."
3859
+ },
3860
+ "topic": {
3861
+ "type": "string",
3862
+ "enum": ["general", "news"],
3863
+ "description": "'news' for news articles, 'general' (default) for web search."
3864
+ },
3865
+ "freshness": {
3866
+ "type": "string",
3867
+ "pattern": "^(day|week|month|year|\\d{4}-\\d{2}-\\d{2}:\\d{4}-\\d{2}-\\d{2})$",
3868
+ "description": "Recency filter: day, week, month, year, or a YYYY-MM-DD:YYYY-MM-DD range."
3869
+ },
3870
+ "include_domains": {
3871
+ "type": "array",
3872
+ "items": {
3873
+ "type": "string",
3874
+ "minLength": 1
3875
+ },
3876
+ "maxItems": 10,
3877
+ "description": "Only return results from these domains, e.g. 'github.com'."
3878
+ },
3879
+ "exclude_domains": {
3880
+ "type": "array",
3881
+ "items": {
3882
+ "type": "string",
3883
+ "minLength": 1
3884
+ },
3885
+ "maxItems": 10,
3886
+ "description": "Exclude results from these domains."
3887
+ }
3888
+ },
3889
+ "description": "Sofya search options.",
3890
+ "additionalProperties": false
3891
+ },
3892
+ "contents": {
3893
+ "type": "object",
3894
+ "properties": {
3895
+ "include_raw_html": {
3896
+ "type": "boolean",
3897
+ "description": "Include the raw HTML source in metadata.raw_html."
3898
+ }
3899
+ },
3900
+ "description": "Sofya contents options.",
3901
+ "additionalProperties": false
3902
+ },
3903
+ "answer": {
3904
+ "type": "object",
3905
+ "properties": {
3906
+ "search_depth": {
3907
+ "type": "string",
3908
+ "enum": ["snippets", "basic"],
3909
+ "description": "'snippets' (1 credit) returns search snippets; 'basic' (2 credits) also reads each page and returns its text in metadata.content."
3910
+ },
3911
+ "max_results": {
3912
+ "type": "integer",
3913
+ "minimum": 1,
3914
+ "maximum": 20,
3915
+ "description": "Search results the answer is grounded in."
3916
+ },
3917
+ "topic": {
3918
+ "type": "string",
3919
+ "enum": ["general", "news"],
3920
+ "description": "'news' for news articles, 'general' (default) for web search."
3921
+ },
3922
+ "freshness": {
3923
+ "type": "string",
3924
+ "pattern": "^(day|week|month|year|\\d{4}-\\d{2}-\\d{2}:\\d{4}-\\d{2}-\\d{2})$",
3925
+ "description": "Recency filter: day, week, month, year, or a YYYY-MM-DD:YYYY-MM-DD range."
3926
+ },
3927
+ "include_domains": {
3928
+ "type": "array",
3929
+ "items": {
3930
+ "type": "string",
3931
+ "minLength": 1
3932
+ },
3933
+ "maxItems": 10,
3934
+ "description": "Only return results from these domains, e.g. 'github.com'."
3935
+ },
3936
+ "exclude_domains": {
3937
+ "type": "array",
3938
+ "items": {
3939
+ "type": "string",
3940
+ "minLength": 1
3941
+ },
3942
+ "maxItems": 10,
3943
+ "description": "Exclude results from these domains."
3944
+ }
3945
+ },
3946
+ "description": "Sofya answer options.",
3947
+ "additionalProperties": false
3948
+ },
3949
+ "research": {
3950
+ "type": "object",
3951
+ "properties": {
3952
+ "topic": {
3953
+ "type": "string",
3954
+ "enum": ["general", "news"],
3955
+ "description": "'news' for news articles, 'general' (default) for web search."
3956
+ },
3957
+ "freshness": {
3958
+ "type": "string",
3959
+ "pattern": "^(day|week|month|year|\\d{4}-\\d{2}-\\d{2}:\\d{4}-\\d{2}-\\d{2})$",
3960
+ "description": "Recency filter: day, week, month, year, or a YYYY-MM-DD:YYYY-MM-DD range."
3961
+ },
3962
+ "max_sources": {
3963
+ "type": "integer",
3964
+ "minimum": 5,
3965
+ "maximum": 30,
3966
+ "description": "Maximum sources to read (default 20)."
3967
+ }
3968
+ },
3969
+ "description": "Sofya research options.",
3970
+ "additionalProperties": false
3971
+ }
3972
+ }
3973
+ }
3974
+ }
3975
+ },
3677
3976
  "tavily": {
3678
3977
  "type": "object",
3679
3978
  "additionalProperties": false,
@@ -15,5 +15,10 @@ export interface IndexedContentsResponse {
15
15
  error?: SerializedError;
16
16
  }>;
17
17
  }
18
+ /**
19
+ * A batch response that leaves out a requested URL has no result for it. This
20
+ * is a failure, unlike a page that the provider returned without content.
21
+ */
22
+ export declare function omittedContents(url: string): ContentsAnswer;
18
23
  /** Only adapters that themselves assemble pages in request order use this helper. */
19
24
  export declare function orderedContents(response: ContentsResponse): IndexedContentsResponse;
@@ -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", "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", "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", "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", "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", "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: string;
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-BTWECET5.js";
8
+ } from "./chunk-6RQGO727.js";
9
9
  import {
10
10
  createWebfox
11
- } from "./chunk-QZFN2747.js";
11
+ } from "./chunk-YILOS4E7.js";
12
12
  import "./chunk-WCTOYZVB.js";
13
- import "./chunk-HCYQF24V.js";
14
- import "./chunk-LTJOWNI2.js";
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-GPACLYNT.js";
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-QZFN2747.js";
9
+ } from "./chunk-YILOS4E7.js";
10
10
  import "./chunk-WCTOYZVB.js";
11
11
  import {
12
12
  CONFIG_SCHEMA_URL
13
- } from "./chunk-HCYQF24V.js";
13
+ } from "./chunk-KMUCUJVN.js";
14
14
  import {
15
15
  validateConfiguredOptions
16
- } from "./chunk-LTJOWNI2.js";
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-GPACLYNT.js";
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-BTWECET5.js";
9
+ } from "./chunk-6RQGO727.js";
9
10
  import {
10
11
  createWebfox,
11
12
  resolveConfigPath
12
- } from "./chunk-QZFN2747.js";
13
+ } from "./chunk-YILOS4E7.js";
13
14
  import "./chunk-WCTOYZVB.js";
14
- import "./chunk-HCYQF24V.js";
15
- import "./chunk-LTJOWNI2.js";
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-GPACLYNT.js";
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", "No results found."));
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
- append(
240
- theme.fg("toolOutput", plainText(result.title)),
241
- theme.fg("accent", number)
242
- );
243
- append(link(result.url, theme), indent);
244
- if (result.snippet)
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
- itemCount?: number;
19
+ sources?: SourceInput[];
11
20
  metadata?: Record<string, unknown>;
12
21
  }
13
22
  export interface ResearchJob {
@@ -76,6 +85,7 @@ export interface ProviderConfigMap {
76
85
  exa: import("./exa/types.js").Exa;
77
86
  firecrawl: import("./firecrawl/types.js").Firecrawl;
78
87
  gemini: import("./gemini/types.js").Gemini;
88
+ keenable: import("./keenable/types.js").Keenable;
79
89
  linkup: import("./linkup/types.js").Linkup;
80
90
  ollama: import("./ollama/types.js").Ollama;
81
91
  openai: import("./openai/types.js").OpenAI;
@@ -83,6 +93,7 @@ export interface ProviderConfigMap {
83
93
  perplexity: import("./perplexity/types.js").Perplexity;
84
94
  serpbase: import("./serpbase/types.js").SerpBase;
85
95
  serper: import("./serper/types.js").Serper;
96
+ sofya: import("./sofya/types.js").Sofya;
86
97
  tavily: import("./tavily/types.js").Tavily;
87
98
  valyu: import("./valyu/types.js").Valyu;
88
99
  youcom: import("./youcom/types.js").Youcom;
@@ -0,0 +1,5 @@
1
+ import type { ProviderContext, ProviderRequest, SearchResponse } from "../contract.js";
2
+ import type { Keenable } from "./types.js";
3
+ export declare const adapter: {
4
+ search(request: ProviderRequest<"search">, config: Keenable, context: ProviderContext): Promise<SearchResponse>;
5
+ };
@@ -0,0 +1 @@
1
+ export declare const keenableProvider: import("../definition.js").ProviderDefinitionFor<"keenable">;
@@ -0,0 +1,4 @@
1
+ import type { Provider } from "../contract.js";
2
+ export interface Keenable extends Provider {
3
+ baseUrl?: string;
4
+ }