scoutline 0.6.4 → 0.7.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 +8 -9
- package/bin/scoutline.js +2 -3
- package/dist/capabilities/crawl.d.ts +93 -0
- package/dist/capabilities/crawl.d.ts.map +1 -0
- package/dist/capabilities/crawl.js +62 -0
- package/dist/capabilities/crawl.js.map +1 -0
- package/dist/capabilities/diagnostics.d.ts +45 -43
- package/dist/capabilities/diagnostics.d.ts.map +1 -1
- package/dist/capabilities/diagnostics.js +58 -71
- package/dist/capabilities/diagnostics.js.map +1 -1
- package/dist/capabilities/map.d.ts +81 -0
- package/dist/capabilities/map.d.ts.map +1 -0
- package/dist/capabilities/map.js +60 -0
- package/dist/capabilities/map.js.map +1 -0
- package/dist/capabilities/quota.js +1 -1
- package/dist/capabilities/quota.js.map +1 -1
- package/dist/capabilities/research.d.ts +98 -0
- package/dist/capabilities/research.d.ts.map +1 -0
- package/dist/capabilities/research.js +71 -0
- package/dist/capabilities/research.js.map +1 -0
- package/dist/capabilities/search.d.ts +9 -1
- package/dist/capabilities/search.d.ts.map +1 -1
- package/dist/commands/crawl.d.ts +46 -0
- package/dist/commands/crawl.d.ts.map +1 -0
- package/dist/commands/crawl.js +170 -0
- package/dist/commands/crawl.js.map +1 -0
- package/dist/commands/doctor.d.ts +7 -8
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +37 -34
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/map.d.ts +39 -0
- package/dist/commands/map.d.ts.map +1 -0
- package/dist/commands/map.js +121 -0
- package/dist/commands/map.js.map +1 -0
- package/dist/commands/read.d.ts.map +1 -1
- package/dist/commands/read.js +7 -1
- package/dist/commands/read.js.map +1 -1
- package/dist/commands/research.d.ts +62 -0
- package/dist/commands/research.d.ts.map +1 -0
- package/dist/commands/research.js +314 -0
- package/dist/commands/research.js.map +1 -0
- package/dist/commands/search.d.ts +2 -1
- package/dist/commands/search.d.ts.map +1 -1
- package/dist/commands/search.js +11 -4
- package/dist/commands/search.js.map +1 -1
- package/dist/index.d.ts +38 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +260 -13
- package/dist/index.js.map +1 -1
- package/dist/lib/cache.d.ts +13 -0
- package/dist/lib/cache.d.ts.map +1 -1
- package/dist/lib/cache.js +15 -0
- package/dist/lib/cache.js.map +1 -1
- package/dist/lib/execution.d.ts +105 -1
- package/dist/lib/execution.d.ts.map +1 -1
- package/dist/lib/execution.js +73 -1
- package/dist/lib/execution.js.map +1 -1
- package/dist/lib/redact.d.ts +2 -1
- package/dist/lib/redact.d.ts.map +1 -1
- package/dist/lib/redact.js +8 -1
- package/dist/lib/redact.js.map +1 -1
- package/dist/lib/research-state.d.ts +104 -0
- package/dist/lib/research-state.d.ts.map +1 -0
- package/dist/lib/research-state.js +214 -0
- package/dist/lib/research-state.js.map +1 -0
- package/dist/lib/search-topic.d.ts +21 -0
- package/dist/lib/search-topic.d.ts.map +1 -0
- package/dist/lib/search-topic.js +36 -0
- package/dist/lib/search-topic.js.map +1 -0
- package/dist/providers/minimax/adapter.d.ts.map +1 -1
- package/dist/providers/minimax/adapter.js +6 -1
- package/dist/providers/minimax/adapter.js.map +1 -1
- package/dist/providers/minimax/vision-conformance.d.ts +2 -2
- package/dist/providers/minimax/vision-conformance.js +2 -2
- package/dist/providers/registry.d.ts.map +1 -1
- package/dist/providers/registry.js +2 -0
- package/dist/providers/registry.js.map +1 -1
- package/dist/providers/tavily/adapter.d.ts +62 -0
- package/dist/providers/tavily/adapter.d.ts.map +1 -0
- package/dist/providers/tavily/adapter.js +970 -0
- package/dist/providers/tavily/adapter.js.map +1 -0
- package/dist/providers/tavily/client.d.ts +184 -0
- package/dist/providers/tavily/client.d.ts.map +1 -0
- package/dist/providers/tavily/client.js +486 -0
- package/dist/providers/tavily/client.js.map +1 -0
- package/dist/providers/tavily/credentials.d.ts +34 -0
- package/dist/providers/tavily/credentials.d.ts.map +1 -0
- package/dist/providers/tavily/credentials.js +56 -0
- package/dist/providers/tavily/credentials.js.map +1 -0
- package/dist/providers/tavily/diagnostics.d.ts +44 -0
- package/dist/providers/tavily/diagnostics.d.ts.map +1 -0
- package/dist/providers/tavily/diagnostics.js +70 -0
- package/dist/providers/tavily/diagnostics.js.map +1 -0
- package/dist/providers/tavily/quota.d.ts +60 -0
- package/dist/providers/tavily/quota.d.ts.map +1 -0
- package/dist/providers/tavily/quota.js +186 -0
- package/dist/providers/tavily/quota.js.map +1 -0
- package/dist/providers/types.d.ts +14 -2
- package/dist/providers/types.d.ts.map +1 -1
- package/dist/providers/types.js +1 -1
- package/dist/providers/types.js.map +1 -1
- package/dist/providers/zai/adapter.d.ts.map +1 -1
- package/dist/providers/zai/adapter.js +6 -1
- package/dist/providers/zai/adapter.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,486 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tavily direct HTTP transport (DESIGN.md §5, §7; tech-plan §7).
|
|
3
|
+
*
|
|
4
|
+
* Performs direct POSTs against the Tavily REST endpoints with an
|
|
5
|
+
* `Authorization: Bearer <apiKey>` header. There is NO internal retry —
|
|
6
|
+
* shared execution owns retry policy. Fetch and timer are injectable for
|
|
7
|
+
* tests.
|
|
8
|
+
*
|
|
9
|
+
* Mirrors `providers/minimax/coding-plan-client.ts` in structure, but
|
|
10
|
+
* SIMPLER: Tavily uses HTTP-status exclusively for errors (no body-level
|
|
11
|
+
* business status code like MiniMax's `base_resp.status_code`). Error
|
|
12
|
+
* responses are `{ "detail": { "error": "message" } }`; the transport
|
|
13
|
+
* maps HTTP status to Scoutline errors at the transport layer only — no
|
|
14
|
+
* second body-parsing layer needed.
|
|
15
|
+
*
|
|
16
|
+
* Boundary rules (ARCHITECTURE.md §2):
|
|
17
|
+
* - May import Adapter-local config and normalized errors.
|
|
18
|
+
* - May import `ProviderQuotaFetch` from `providers/types.ts`.
|
|
19
|
+
* - Must NOT import command presentation, capability contracts, or
|
|
20
|
+
* another Provider's Adapter.
|
|
21
|
+
* - Must NOT perform response field normalization — the Adapter owns
|
|
22
|
+
* that. This module declares Provider-native request-body types
|
|
23
|
+
* only (Tavily API field names); it does not import SearchControls
|
|
24
|
+
* or any capability contract.
|
|
25
|
+
*/
|
|
26
|
+
import { createRequire } from "node:module";
|
|
27
|
+
import { ApiError, AuthError, NetworkError, TimeoutError } from "../../lib/errors.js";
|
|
28
|
+
const require = createRequire(import.meta.url);
|
|
29
|
+
const { version: VERSION } = require("../../../package.json");
|
|
30
|
+
const BASE_URL = "https://api.tavily.com";
|
|
31
|
+
const SEARCH_PATH = "/search";
|
|
32
|
+
const EXTRACT_PATH = "/extract";
|
|
33
|
+
const CRAWL_PATH = "/crawl";
|
|
34
|
+
const MAP_PATH = "/map";
|
|
35
|
+
const RESEARCH_PATH = "/research";
|
|
36
|
+
const USAGE_PATH = "/usage";
|
|
37
|
+
const DEFAULT_TIMEOUT_MS = 30000;
|
|
38
|
+
const USER_AGENT = `scoutline/${VERSION}`;
|
|
39
|
+
const TIMEOUT_HELP_TEXT = "Try again or increase timeout with TAVILY_TIMEOUT env var";
|
|
40
|
+
function resolveTimeoutMs(env) {
|
|
41
|
+
const raw = parseInt(env.TAVILY_TIMEOUT || String(DEFAULT_TIMEOUT_MS), 10);
|
|
42
|
+
return Number.isFinite(raw) && raw > 0 ? raw : DEFAULT_TIMEOUT_MS;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Layer 1 — HTTP-status mapping. Runs BEFORE the body is parsed; on a
|
|
46
|
+
* non-200 response we discard the body and throw a typed error.
|
|
47
|
+
*
|
|
48
|
+
* Tavily uses HTTP-status exclusively. The non-standard 432/433 codes
|
|
49
|
+
* are Tavily-specific plan/paygo limits; they are mapped to `ApiError`
|
|
50
|
+
* (NOT `QuotaError`, which hardcodes statusCode 429 and would collide
|
|
51
|
+
* with actual rate limits) with the real status preserved so scripting
|
|
52
|
+
* users can distinguish plan-limit from paygo-limit from rate-limit.
|
|
53
|
+
* Both are terminal because `isOperationRetryableError` treats an
|
|
54
|
+
* `ApiError` with non-429/non-5xx status as non-retryable.
|
|
55
|
+
*
|
|
56
|
+
* `timeoutMs` is forwarded so 408/504 can throw `TimeoutError`
|
|
57
|
+
* carrying the configured duration (and the `TAVILY_TIMEOUT` help
|
|
58
|
+
* text). The transport never embeds credential material in any error
|
|
59
|
+
* message.
|
|
60
|
+
*/
|
|
61
|
+
function mapStatusError(status, timeoutMs) {
|
|
62
|
+
if (status === 401 || status === 403) {
|
|
63
|
+
return new AuthError("Tavily authentication failed", "TAVILY_API_KEY");
|
|
64
|
+
}
|
|
65
|
+
if (status === 408 || status === 504) {
|
|
66
|
+
return new TimeoutError(timeoutMs, TIMEOUT_HELP_TEXT);
|
|
67
|
+
}
|
|
68
|
+
if (status === 429) {
|
|
69
|
+
return new ApiError("Tavily rate limit exceeded", 429);
|
|
70
|
+
}
|
|
71
|
+
if (status === 432) {
|
|
72
|
+
return new ApiError("Tavily plan limit exceeded. Upgrade your plan at app.tavily.com.", 432);
|
|
73
|
+
}
|
|
74
|
+
if (status === 433) {
|
|
75
|
+
return new ApiError("Tavily pay-as-you-go limit exceeded. Increase your limit on the Tavily dashboard.", 433);
|
|
76
|
+
}
|
|
77
|
+
if (status === 400 || status === 404 || status === 410 || status === 422) {
|
|
78
|
+
return new ApiError("Tavily request failed", status);
|
|
79
|
+
}
|
|
80
|
+
if (status >= 500) {
|
|
81
|
+
return new ApiError("Tavily request failed", status);
|
|
82
|
+
}
|
|
83
|
+
return new ApiError("Tavily request failed", status);
|
|
84
|
+
}
|
|
85
|
+
function normalizeTransportError(err, timeoutMs) {
|
|
86
|
+
if (err instanceof AuthError || err instanceof ApiError || err instanceof TimeoutError) {
|
|
87
|
+
return err;
|
|
88
|
+
}
|
|
89
|
+
if (err instanceof Error) {
|
|
90
|
+
if (err.name === "AbortError") {
|
|
91
|
+
return new TimeoutError(timeoutMs, TIMEOUT_HELP_TEXT);
|
|
92
|
+
}
|
|
93
|
+
const lower = err.message.toLowerCase();
|
|
94
|
+
if (lower.includes("fetch") ||
|
|
95
|
+
lower.includes("econnrefused") ||
|
|
96
|
+
lower.includes("econnreset") ||
|
|
97
|
+
lower.includes("enotfound") ||
|
|
98
|
+
lower.includes("network")) {
|
|
99
|
+
return new NetworkError("Tavily network error");
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return new ApiError("Tavily request failed", 500);
|
|
103
|
+
}
|
|
104
|
+
async function postTavilyJson(apiKey, path, body, deps, endpointLabel,
|
|
105
|
+
/**
|
|
106
|
+
* Optional client-side AbortController timeout in ms. When omitted, the
|
|
107
|
+
* transport resolves the timeout from `deps.env` (`TAVILY_TIMEOUT`,
|
|
108
|
+
* default 30s). Crawl passes an explicit value so the client waits at
|
|
109
|
+
* least as long as the server-side `body.timeout` ceiling (150s default).
|
|
110
|
+
*/
|
|
111
|
+
timeoutMsOverride) {
|
|
112
|
+
const f = deps.fetch ?? fetch;
|
|
113
|
+
const setT = deps.setTimeout ?? setTimeout;
|
|
114
|
+
const clearT = deps.clearTimeout ?? clearTimeout;
|
|
115
|
+
const env = deps.env ?? process.env;
|
|
116
|
+
const timeoutMs = timeoutMsOverride ?? resolveTimeoutMs(env);
|
|
117
|
+
const url = `${BASE_URL}${path}`;
|
|
118
|
+
const controller = new AbortController();
|
|
119
|
+
const timeoutId = setT(() => controller.abort(), timeoutMs);
|
|
120
|
+
try {
|
|
121
|
+
const res = await f(url, {
|
|
122
|
+
method: "POST",
|
|
123
|
+
headers: {
|
|
124
|
+
Authorization: `Bearer ${apiKey}`,
|
|
125
|
+
"Content-Type": "application/json",
|
|
126
|
+
"User-Agent": USER_AGENT,
|
|
127
|
+
},
|
|
128
|
+
body: JSON.stringify(body),
|
|
129
|
+
signal: controller.signal,
|
|
130
|
+
});
|
|
131
|
+
clearT(timeoutId);
|
|
132
|
+
if (!res.ok) {
|
|
133
|
+
await res.text().catch(() => { });
|
|
134
|
+
throw mapStatusError(res.status, timeoutMs);
|
|
135
|
+
}
|
|
136
|
+
let parsed;
|
|
137
|
+
try {
|
|
138
|
+
parsed = await res.json();
|
|
139
|
+
}
|
|
140
|
+
catch {
|
|
141
|
+
throw new ApiError(`Tavily ${endpointLabel} returned a malformed response`, 500);
|
|
142
|
+
}
|
|
143
|
+
return parsed;
|
|
144
|
+
}
|
|
145
|
+
catch (err) {
|
|
146
|
+
clearT(timeoutId);
|
|
147
|
+
throw normalizeTransportError(err, timeoutMs);
|
|
148
|
+
}
|
|
149
|
+
finally {
|
|
150
|
+
controller.abort();
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Perform ONE POST against the Tavily /search endpoint. No retry; no
|
|
155
|
+
* response body in public errors. Returns the parsed JSON body (raw;
|
|
156
|
+
* the Adapter post-processes into normalized search sources).
|
|
157
|
+
*
|
|
158
|
+
* `params` carries Tavily-native API fields already mapped from
|
|
159
|
+
* `SearchControls` by the Adapter.
|
|
160
|
+
*/
|
|
161
|
+
export async function fetchTavilySearch(apiKey, query, params, deps = {}) {
|
|
162
|
+
const body = { query };
|
|
163
|
+
if (params) {
|
|
164
|
+
if (params.topic !== undefined) {
|
|
165
|
+
body.topic = params.topic;
|
|
166
|
+
}
|
|
167
|
+
if (params.search_depth !== undefined) {
|
|
168
|
+
body.search_depth = params.search_depth;
|
|
169
|
+
}
|
|
170
|
+
if (params.include_domains !== undefined) {
|
|
171
|
+
body.include_domains = [...params.include_domains];
|
|
172
|
+
}
|
|
173
|
+
if (params.time_range !== undefined) {
|
|
174
|
+
body.time_range = params.time_range;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return postTavilyJson(apiKey, SEARCH_PATH, body, deps, "search");
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Perform ONE POST against the Tavily /extract endpoint. No retry; no
|
|
181
|
+
* response body in public errors. Returns the parsed JSON body (raw;
|
|
182
|
+
* the Adapter post-processes into a normalized ReaderFetchResult).
|
|
183
|
+
*
|
|
184
|
+
* `url` is a single URL; the transport wraps it as `urls: [url]` per
|
|
185
|
+
* the Tavily API contract.
|
|
186
|
+
*/
|
|
187
|
+
export async function fetchTavilyExtract(apiKey, url, params, deps = {}) {
|
|
188
|
+
const body = { urls: [url] };
|
|
189
|
+
if (params?.extract_depth !== undefined) {
|
|
190
|
+
body.extract_depth = params.extract_depth;
|
|
191
|
+
}
|
|
192
|
+
return postTavilyJson(apiKey, EXTRACT_PATH, body, deps, "extract");
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Perform ONE POST against the Tavily /crawl endpoint. No retry; no
|
|
196
|
+
* response body in public errors. Returns the parsed JSON body (raw; the
|
|
197
|
+
* Adapter post-processes into a normalized CrawlResult).
|
|
198
|
+
*
|
|
199
|
+
* `params` carries Tavily-native API fields already mapped from
|
|
200
|
+
* `CrawlRequest` by the Adapter.
|
|
201
|
+
*/
|
|
202
|
+
export async function fetchTavilyCrawl(apiKey, url, params, deps = {}) {
|
|
203
|
+
const body = { url };
|
|
204
|
+
if (params) {
|
|
205
|
+
if (params.max_depth !== undefined) {
|
|
206
|
+
body.max_depth = params.max_depth;
|
|
207
|
+
}
|
|
208
|
+
if (params.max_breadth !== undefined) {
|
|
209
|
+
body.max_breadth = params.max_breadth;
|
|
210
|
+
}
|
|
211
|
+
if (params.limit !== undefined) {
|
|
212
|
+
body.limit = params.limit;
|
|
213
|
+
}
|
|
214
|
+
if (params.select_paths !== undefined) {
|
|
215
|
+
body.select_paths = [...params.select_paths];
|
|
216
|
+
}
|
|
217
|
+
if (params.exclude_paths !== undefined) {
|
|
218
|
+
body.exclude_paths = [...params.exclude_paths];
|
|
219
|
+
}
|
|
220
|
+
if (params.instructions !== undefined) {
|
|
221
|
+
body.instructions = params.instructions;
|
|
222
|
+
}
|
|
223
|
+
if (params.format !== undefined) {
|
|
224
|
+
body.format = params.format;
|
|
225
|
+
}
|
|
226
|
+
if (params.extract_depth !== undefined) {
|
|
227
|
+
body.extract_depth = params.extract_depth;
|
|
228
|
+
}
|
|
229
|
+
if (params.timeout !== undefined) {
|
|
230
|
+
body.timeout = params.timeout;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
// The client-side AbortController MUST wait at least as long as the
|
|
234
|
+
// server-side ceiling. Tavily's crawl `timeout` (seconds) caps how long
|
|
235
|
+
// the server works; the default is 150s. If the transport default
|
|
236
|
+
// (`TAVILY_TIMEOUT`, 30s) is shorter, any crawl exceeding it would be
|
|
237
|
+
// aborted client-side regardless of `--timeout`. Take the larger of the
|
|
238
|
+
// transport default and (server ceiling * 1000 + 5s network buffer).
|
|
239
|
+
const serverCeilingSeconds = params?.timeout ?? 150;
|
|
240
|
+
const clientTimeoutMs = Math.max(resolveTimeoutMs(deps.env ?? process.env), serverCeilingSeconds * 1000 + 5000);
|
|
241
|
+
return postTavilyJson(apiKey, CRAWL_PATH, body, deps, "crawl", clientTimeoutMs);
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Perform ONE POST against the Tavily /map endpoint. No retry; no
|
|
245
|
+
* response body in public errors. Returns the parsed JSON body (raw; the
|
|
246
|
+
* Adapter post-processes into a normalized MapResult).
|
|
247
|
+
*
|
|
248
|
+
* `params` carries Tavily-native API fields already mapped from
|
|
249
|
+
* `MapRequest` by the Adapter. The /map response is `{ results: string[] }`
|
|
250
|
+
* — an array of URL strings, NOT an array of page objects — and is
|
|
251
|
+
* returned as raw `unknown` for the Adapter to normalize.
|
|
252
|
+
*/
|
|
253
|
+
export async function fetchTavilyMap(apiKey, url, params, deps = {}) {
|
|
254
|
+
const body = { url };
|
|
255
|
+
if (params) {
|
|
256
|
+
if (params.max_depth !== undefined) {
|
|
257
|
+
body.max_depth = params.max_depth;
|
|
258
|
+
}
|
|
259
|
+
if (params.max_breadth !== undefined) {
|
|
260
|
+
body.max_breadth = params.max_breadth;
|
|
261
|
+
}
|
|
262
|
+
if (params.limit !== undefined) {
|
|
263
|
+
body.limit = params.limit;
|
|
264
|
+
}
|
|
265
|
+
if (params.select_paths !== undefined) {
|
|
266
|
+
body.select_paths = [...params.select_paths];
|
|
267
|
+
}
|
|
268
|
+
if (params.exclude_paths !== undefined) {
|
|
269
|
+
body.exclude_paths = [...params.exclude_paths];
|
|
270
|
+
}
|
|
271
|
+
if (params.instructions !== undefined) {
|
|
272
|
+
body.instructions = params.instructions;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
return postTavilyJson(apiKey, MAP_PATH, body, deps, "map");
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Layer 1 — HTTP-status mapping for GET requests. Same semantics as
|
|
279
|
+
* `postTavilyJson`'s mapping (`mapStatusError`); duplicated here so a
|
|
280
|
+
* transport seam that only ever issues GETs does not have to import
|
|
281
|
+
* the POST-only path.
|
|
282
|
+
*/
|
|
283
|
+
async function getTavilyJson(apiKey, path, deps, endpointLabel) {
|
|
284
|
+
const f = deps.fetch ?? fetch;
|
|
285
|
+
const setT = deps.setTimeout ?? setTimeout;
|
|
286
|
+
const clearT = deps.clearTimeout ?? clearTimeout;
|
|
287
|
+
const env = deps.env ?? process.env;
|
|
288
|
+
const timeoutMs = resolveTimeoutMs(env);
|
|
289
|
+
const url = `${BASE_URL}${path}`;
|
|
290
|
+
const controller = new AbortController();
|
|
291
|
+
const timeoutId = setT(() => controller.abort(), timeoutMs);
|
|
292
|
+
try {
|
|
293
|
+
const res = await f(url, {
|
|
294
|
+
method: "GET",
|
|
295
|
+
headers: {
|
|
296
|
+
Authorization: `Bearer ${apiKey}`,
|
|
297
|
+
"User-Agent": USER_AGENT,
|
|
298
|
+
},
|
|
299
|
+
signal: controller.signal,
|
|
300
|
+
});
|
|
301
|
+
clearT(timeoutId);
|
|
302
|
+
if (!res.ok) {
|
|
303
|
+
await res.text().catch(() => { });
|
|
304
|
+
throw mapStatusError(res.status, timeoutMs);
|
|
305
|
+
}
|
|
306
|
+
let parsed;
|
|
307
|
+
try {
|
|
308
|
+
parsed = await res.json();
|
|
309
|
+
}
|
|
310
|
+
catch {
|
|
311
|
+
throw new ApiError(`Tavily ${endpointLabel} returned a malformed response`, 500);
|
|
312
|
+
}
|
|
313
|
+
return parsed;
|
|
314
|
+
}
|
|
315
|
+
catch (err) {
|
|
316
|
+
clearT(timeoutId);
|
|
317
|
+
throw normalizeTransportError(err, timeoutMs);
|
|
318
|
+
}
|
|
319
|
+
finally {
|
|
320
|
+
controller.abort();
|
|
321
|
+
}
|
|
322
|
+
} /**
|
|
323
|
+
* Perform ONE GET against the Tavily /usage endpoint. No retry; no
|
|
324
|
+
* response body in public errors. Returns the parsed JSON body (raw;
|
|
325
|
+
* the Adapter post-processes into normalized quota categories).
|
|
326
|
+
*
|
|
327
|
+
* Tavily's /usage is rate-limited (10 calls per 10 minutes per key).
|
|
328
|
+
* It is therefore ONLY safe to invoke through the Quota Capability
|
|
329
|
+
* path (interactive `quota` command) — the Diagnostics Capability
|
|
330
|
+
* intentionally uses /search (1 credit) to avoid hitting this
|
|
331
|
+
* restrictive window.
|
|
332
|
+
*/
|
|
333
|
+
export async function fetchTavilyUsage(apiKey, deps = {}) {
|
|
334
|
+
return getTavilyJson(apiKey, USAGE_PATH, deps, "usage");
|
|
335
|
+
}
|
|
336
|
+
// ---------------------------------------------------------------------------
|
|
337
|
+
// Research — async create/poll transport (tech-plan §3, §7)
|
|
338
|
+
// ---------------------------------------------------------------------------
|
|
339
|
+
//
|
|
340
|
+
// Research is the only Tavily capability with an asynchronous lifecycle:
|
|
341
|
+
// POST /research creates the task (HTTP 201, { request_id, status }),
|
|
342
|
+
// then GET /research/{id} polls until completion (200 completed), failure
|
|
343
|
+
// (200 failed), or the task disappears (404). The transport performs ONE
|
|
344
|
+
// request per call and never polls internally — the Adapter's `invoke()`
|
|
345
|
+
// owns the poll loop and the state file.
|
|
346
|
+
/**
|
|
347
|
+
* Perform ONE POST against the Tavily /research endpoint. No retry; no
|
|
348
|
+
* response body in public errors. Returns the structured create result
|
|
349
|
+
* `{ requestId, status }`.
|
|
350
|
+
*
|
|
351
|
+
* Note: /research returns HTTP 201 (Created) on success, not 200. The
|
|
352
|
+
* shared `postTavilyJson` treats any 2xx as success (`res.ok`), so 201
|
|
353
|
+
* is handled correctly without special-casing the status mapping.
|
|
354
|
+
*/
|
|
355
|
+
export async function createTavilyResearch(apiKey, query, params, deps = {}) {
|
|
356
|
+
const body = { input: query };
|
|
357
|
+
if (params) {
|
|
358
|
+
if (params.model !== undefined)
|
|
359
|
+
body.model = params.model;
|
|
360
|
+
if (params.output_length !== undefined)
|
|
361
|
+
body.output_length = params.output_length;
|
|
362
|
+
if (params.citation_format !== undefined)
|
|
363
|
+
body.citation_format = params.citation_format;
|
|
364
|
+
if (params.domain !== undefined)
|
|
365
|
+
body.include_domains = [params.domain];
|
|
366
|
+
}
|
|
367
|
+
const raw = (await postTavilyJson(apiKey, RESEARCH_PATH, body, deps, "research"));
|
|
368
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
|
|
369
|
+
throw new ApiError("Tavily research returned a malformed response", 500);
|
|
370
|
+
}
|
|
371
|
+
const obj = raw;
|
|
372
|
+
const requestId = obj.request_id;
|
|
373
|
+
const status = obj.status;
|
|
374
|
+
if (typeof requestId !== "string" || requestId.length === 0) {
|
|
375
|
+
throw new ApiError("Tavily research returned a malformed response", 500);
|
|
376
|
+
}
|
|
377
|
+
return { requestId, status: typeof status === "string" ? status : "pending" };
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* Perform ONE GET against the Tavily /research/{request_id} endpoint.
|
|
381
|
+
* No retry. Returns a structured poll result.
|
|
382
|
+
*
|
|
383
|
+
* Unlike other GETs, a 404 is NOT a terminal transport error here: it
|
|
384
|
+
* means the server-side task has expired/disappeared, so the Adapter can
|
|
385
|
+
* delete the stale state file and create a fresh task. The poll result
|
|
386
|
+
* carries `status: "not_found"` for that case. All other non-2xx statuses
|
|
387
|
+
* throw the standard mapped error (auth, rate limit, 5xx).
|
|
388
|
+
*/
|
|
389
|
+
export async function pollTavilyResearch(apiKey, requestId, deps = {}) {
|
|
390
|
+
const f = deps.fetch ?? fetch;
|
|
391
|
+
const setT = deps.setTimeout ?? setTimeout;
|
|
392
|
+
const clearT = deps.clearTimeout ?? clearTimeout;
|
|
393
|
+
const env = deps.env ?? process.env;
|
|
394
|
+
const timeoutMs = resolveTimeoutMs(env);
|
|
395
|
+
const url = `${BASE_URL}${RESEARCH_PATH}/${encodeURIComponent(requestId)}`;
|
|
396
|
+
const controller = new AbortController();
|
|
397
|
+
const timeoutId = setT(() => controller.abort(), timeoutMs);
|
|
398
|
+
try {
|
|
399
|
+
let res;
|
|
400
|
+
try {
|
|
401
|
+
res = await f(url, {
|
|
402
|
+
method: "GET",
|
|
403
|
+
headers: {
|
|
404
|
+
Authorization: `Bearer ${apiKey}`,
|
|
405
|
+
"User-Agent": USER_AGENT,
|
|
406
|
+
},
|
|
407
|
+
signal: controller.signal,
|
|
408
|
+
});
|
|
409
|
+
clearT(timeoutId);
|
|
410
|
+
}
|
|
411
|
+
catch (err) {
|
|
412
|
+
clearT(timeoutId);
|
|
413
|
+
throw normalizeTransportError(err, timeoutMs);
|
|
414
|
+
}
|
|
415
|
+
if (res.status === 404) {
|
|
416
|
+
await res.text().catch(() => { });
|
|
417
|
+
return { status: "not_found" };
|
|
418
|
+
}
|
|
419
|
+
if (!res.ok) {
|
|
420
|
+
await res.text().catch(() => { });
|
|
421
|
+
throw mapStatusError(res.status, timeoutMs);
|
|
422
|
+
}
|
|
423
|
+
let parsed;
|
|
424
|
+
try {
|
|
425
|
+
parsed = await res.json();
|
|
426
|
+
}
|
|
427
|
+
catch {
|
|
428
|
+
throw new ApiError("Tavily research returned a malformed response", 500);
|
|
429
|
+
}
|
|
430
|
+
return normalizeResearchPollResult(parsed);
|
|
431
|
+
}
|
|
432
|
+
finally {
|
|
433
|
+
controller.abort();
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
/**
|
|
437
|
+
* Normalize a parsed poll body into a {@link TavilyResearchPollResult}.
|
|
438
|
+
* Accepts `{ status, content?, sources? }`. Unknown/missing status maps
|
|
439
|
+
* to a malformed-response error so the Adapter never silently advances
|
|
440
|
+
* on garbage.
|
|
441
|
+
*/
|
|
442
|
+
function normalizeResearchPollResult(value) {
|
|
443
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
444
|
+
throw new ApiError("Tavily research returned a malformed response", 500);
|
|
445
|
+
}
|
|
446
|
+
const obj = value;
|
|
447
|
+
const status = obj.status;
|
|
448
|
+
if (status !== "pending" &&
|
|
449
|
+
status !== "in_progress" &&
|
|
450
|
+
status !== "completed" &&
|
|
451
|
+
status !== "failed") {
|
|
452
|
+
throw new ApiError("Tavily research returned a malformed response", 500);
|
|
453
|
+
}
|
|
454
|
+
const result = { status };
|
|
455
|
+
if (status === "completed") {
|
|
456
|
+
const content = obj.content;
|
|
457
|
+
if (typeof content !== "string") {
|
|
458
|
+
throw new ApiError("Tavily research returned a malformed response", 500);
|
|
459
|
+
}
|
|
460
|
+
const sources = obj.sources;
|
|
461
|
+
if (sources !== undefined && !Array.isArray(sources)) {
|
|
462
|
+
throw new ApiError("Tavily research returned a malformed response", 500);
|
|
463
|
+
}
|
|
464
|
+
let decodedSources;
|
|
465
|
+
if (Array.isArray(sources)) {
|
|
466
|
+
decodedSources = [];
|
|
467
|
+
for (const entry of sources) {
|
|
468
|
+
if (!entry || typeof entry !== "object" || Array.isArray(entry)) {
|
|
469
|
+
throw new ApiError("Tavily research returned a malformed response", 500);
|
|
470
|
+
}
|
|
471
|
+
const src = entry;
|
|
472
|
+
decodedSources.push({
|
|
473
|
+
title: typeof src.title === "string" ? src.title : undefined,
|
|
474
|
+
url: typeof src.url === "string" ? src.url : undefined,
|
|
475
|
+
});
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
return {
|
|
479
|
+
status: "completed",
|
|
480
|
+
content,
|
|
481
|
+
...(decodedSources !== undefined ? { sources: decodedSources } : {}),
|
|
482
|
+
};
|
|
483
|
+
}
|
|
484
|
+
return result;
|
|
485
|
+
}
|
|
486
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../../src/providers/tavily/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tavily credential resolution (DESIGN.md §6, tech-plan §7).
|
|
3
|
+
*
|
|
4
|
+
* Single source of truth for the Tavily API key. Whitespace-only values
|
|
5
|
+
* are treated as absent, matching the descriptor's `isConfigured`
|
|
6
|
+
* contract.
|
|
7
|
+
*
|
|
8
|
+
* Boundary rules (ARCHITECTURE.md §2):
|
|
9
|
+
* - May import the normalized-error contract only.
|
|
10
|
+
* - Must NOT import transport, command presentation, or another
|
|
11
|
+
* Provider's Adapter.
|
|
12
|
+
*
|
|
13
|
+
* Missing credentials are surfaced as {@link ConfigurationError}
|
|
14
|
+
* (exit 3), distinct from {@link AuthError} (exit 1) which means the
|
|
15
|
+
* Provider REJECTED a presented credential.
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* Resolve the Tavily API key without throwing. Returns `undefined`
|
|
19
|
+
* when no non-blank value is present.
|
|
20
|
+
*/
|
|
21
|
+
export declare function resolveTavilyApiKey(env: NodeJS.ProcessEnv): string | undefined;
|
|
22
|
+
/**
|
|
23
|
+
* Resolve the Tavily API key or throw {@link ConfigurationError}
|
|
24
|
+
* (exit 3) when it is missing. Call this at every capability
|
|
25
|
+
* invocation gate.
|
|
26
|
+
*/
|
|
27
|
+
export declare function requireTavilyApiKey(env: NodeJS.ProcessEnv): string;
|
|
28
|
+
/**
|
|
29
|
+
* True when a non-blank Tavily API key is configured. Metadata-only:
|
|
30
|
+
* performs no transport construction and reads no other Provider's
|
|
31
|
+
* credentials.
|
|
32
|
+
*/
|
|
33
|
+
export declare function isTavilyConfigured(env: NodeJS.ProcessEnv): boolean;
|
|
34
|
+
//# sourceMappingURL=credentials.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../../../src/providers/tavily/credentials.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAgBH;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG,MAAM,GAAG,SAAS,CAE9E;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG,MAAM,CASlE;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG,OAAO,CAElE"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tavily credential resolution (DESIGN.md §6, tech-plan §7).
|
|
3
|
+
*
|
|
4
|
+
* Single source of truth for the Tavily API key. Whitespace-only values
|
|
5
|
+
* are treated as absent, matching the descriptor's `isConfigured`
|
|
6
|
+
* contract.
|
|
7
|
+
*
|
|
8
|
+
* Boundary rules (ARCHITECTURE.md §2):
|
|
9
|
+
* - May import the normalized-error contract only.
|
|
10
|
+
* - Must NOT import transport, command presentation, or another
|
|
11
|
+
* Provider's Adapter.
|
|
12
|
+
*
|
|
13
|
+
* Missing credentials are surfaced as {@link ConfigurationError}
|
|
14
|
+
* (exit 3), distinct from {@link AuthError} (exit 1) which means the
|
|
15
|
+
* Provider REJECTED a presented credential.
|
|
16
|
+
*/
|
|
17
|
+
import { ConfigurationError } from "../../lib/errors.js";
|
|
18
|
+
const MISSING_KEY_HELP = 'export TAVILY_API_KEY="your-api-key"';
|
|
19
|
+
/**
|
|
20
|
+
* Pick a non-blank raw value from the environment. Returns the original
|
|
21
|
+
* (untrimmed) string when it contains at least one non-whitespace
|
|
22
|
+
* character, otherwise `undefined`.
|
|
23
|
+
*/
|
|
24
|
+
function pickNonBlank(raw) {
|
|
25
|
+
if (typeof raw !== "string")
|
|
26
|
+
return undefined;
|
|
27
|
+
return raw.trim().length > 0 ? raw : undefined;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Resolve the Tavily API key without throwing. Returns `undefined`
|
|
31
|
+
* when no non-blank value is present.
|
|
32
|
+
*/
|
|
33
|
+
export function resolveTavilyApiKey(env) {
|
|
34
|
+
return pickNonBlank(env.TAVILY_API_KEY);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Resolve the Tavily API key or throw {@link ConfigurationError}
|
|
38
|
+
* (exit 3) when it is missing. Call this at every capability
|
|
39
|
+
* invocation gate.
|
|
40
|
+
*/
|
|
41
|
+
export function requireTavilyApiKey(env) {
|
|
42
|
+
const key = resolveTavilyApiKey(env);
|
|
43
|
+
if (key === undefined) {
|
|
44
|
+
throw new ConfigurationError("TAVILY_API_KEY environment variable is required", MISSING_KEY_HELP);
|
|
45
|
+
}
|
|
46
|
+
return key;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* True when a non-blank Tavily API key is configured. Metadata-only:
|
|
50
|
+
* performs no transport construction and reads no other Provider's
|
|
51
|
+
* credentials.
|
|
52
|
+
*/
|
|
53
|
+
export function isTavilyConfigured(env) {
|
|
54
|
+
return resolveTavilyApiKey(env) !== undefined;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=credentials.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credentials.js","sourceRoot":"","sources":["../../../src/providers/tavily/credentials.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAEzD,MAAM,gBAAgB,GAAG,sCAAsC,CAAC;AAEhE;;;;GAIG;AACH,SAAS,YAAY,CAAC,GAAY;IAChC,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC;IAC9C,OAAO,GAAG,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;AACjD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,GAAsB;IACxD,OAAO,YAAY,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;AAC1C,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,GAAsB;IACxD,MAAM,GAAG,GAAG,mBAAmB,CAAC,GAAG,CAAC,CAAC;IACrC,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;QACtB,MAAM,IAAI,kBAAkB,CAC1B,iDAAiD,EACjD,gBAAgB,CACjB,CAAC;IACJ,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAAC,GAAsB;IACvD,OAAO,mBAAmB,CAAC,GAAG,CAAC,KAAK,SAAS,CAAC;AAChD,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tavily Diagnostics Capability (DESIGN.md §14, tech-plan §10, T08).
|
|
3
|
+
*
|
|
4
|
+
* Probes Tavily connectivity with a single, cheapest-possible request
|
|
5
|
+
* — `/search` with `search_depth: "basic"` and a stub query — so the
|
|
6
|
+
* doctor command can verify a credential authenticates without
|
|
7
|
+
* burning plan credits.
|
|
8
|
+
*
|
|
9
|
+
* The probe intentionally avoids `/usage`. Tavily throttles `/usage`
|
|
10
|
+
* to 10 requests per 10 minutes per key (tech-plan §10), which would
|
|
11
|
+
* make a routine doctor run rate-limit itself. `/search` with basic
|
|
12
|
+
* depth costs a single credit and is bounded by the search rate limit,
|
|
13
|
+
* which is far more generous than the usage endpoint.
|
|
14
|
+
*
|
|
15
|
+
* Boundary rules (ARCHITECTURE.md §2):
|
|
16
|
+
* - May import the diagnostics capability contract, Adapter-local
|
|
17
|
+
* config, Adapter-local search transport, and normalized errors.
|
|
18
|
+
* - Must NOT import command presentation or another Provider's
|
|
19
|
+
* Adapter.
|
|
20
|
+
*/
|
|
21
|
+
import type { DiagnosticsCapability } from "../../capabilities/diagnostics.js";
|
|
22
|
+
import { type TavilyTransportDeps } from "./client.js";
|
|
23
|
+
/**
|
|
24
|
+
* Options for the Tavily DiagnosticsCapability. The API key is
|
|
25
|
+
* resolved from `env`; transport dependencies (`fetch`, timer) are
|
|
26
|
+
* injectable for deterministic tests through the unified `transport`
|
|
27
|
+
* seam.
|
|
28
|
+
*/
|
|
29
|
+
export interface TavilyDiagnosticsCapabilityOptions {
|
|
30
|
+
readonly env: NodeJS.ProcessEnv;
|
|
31
|
+
readonly transport?: TavilyTransportDeps;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Build the Tavily DiagnosticsCapability. The probe performs ONE
|
|
35
|
+
* `/search` request with `search_depth: "basic"` and a stub query so
|
|
36
|
+
* it costs a single credit. Shared execution owns the retry policy;
|
|
37
|
+
* this transport performs exactly one attempt per invocation.
|
|
38
|
+
*
|
|
39
|
+
* When `options.probe` is false, `invoke` resolves immediately without
|
|
40
|
+
* touching the network — the doctor command skips probing unconfigured
|
|
41
|
+
* or tools-disabled Providers before reaching this Capability.
|
|
42
|
+
*/
|
|
43
|
+
export declare function createTavilyDiagnosticsCapability(options: TavilyDiagnosticsCapabilityOptions): DiagnosticsCapability;
|
|
44
|
+
//# sourceMappingURL=diagnostics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diagnostics.d.ts","sourceRoot":"","sources":["../../../src/providers/tavily/diagnostics.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EACV,qBAAqB,EAEtB,MAAM,mCAAmC,CAAC;AAS3C,OAAO,EAEL,KAAK,mBAAmB,EACzB,MAAM,aAAa,CAAC;AA6BrB;;;;;GAKG;AACH,MAAM,WAAW,kCAAkC;IACjD,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;IAChC,QAAQ,CAAC,SAAS,CAAC,EAAE,mBAAmB,CAAC;CAC1C;AAED;;;;;;;;;GASG;AACH,wBAAgB,iCAAiC,CAC/C,OAAO,EAAE,kCAAkC,GAC1C,qBAAqB,CAcvB"}
|