scoutline 0.12.0 → 0.13.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 (92) hide show
  1. package/README.md +24 -24
  2. package/dist/commands/crawl.js +1 -1
  3. package/dist/commands/doctor.js +1 -1
  4. package/dist/commands/init.d.ts.map +1 -1
  5. package/dist/commands/init.js +18 -0
  6. package/dist/commands/init.js.map +1 -1
  7. package/dist/commands/map.js +1 -1
  8. package/dist/commands/quota.js +1 -1
  9. package/dist/commands/read.d.ts.map +1 -1
  10. package/dist/commands/read.js +6 -2
  11. package/dist/commands/read.js.map +1 -1
  12. package/dist/commands/research.d.ts.map +1 -1
  13. package/dist/commands/research.js +8 -2
  14. package/dist/commands/research.js.map +1 -1
  15. package/dist/commands/search.js +1 -1
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +6 -3
  18. package/dist/index.js.map +1 -1
  19. package/dist/lib/provider-fallback.d.ts +13 -10
  20. package/dist/lib/provider-fallback.d.ts.map +1 -1
  21. package/dist/lib/provider-fallback.js +40 -25
  22. package/dist/lib/provider-fallback.js.map +1 -1
  23. package/dist/lib/quota-mapping.d.ts +4 -2
  24. package/dist/lib/quota-mapping.d.ts.map +1 -1
  25. package/dist/lib/quota-mapping.js +19 -2
  26. package/dist/lib/quota-mapping.js.map +1 -1
  27. package/dist/lib/redact.d.ts.map +1 -1
  28. package/dist/lib/redact.js +9 -0
  29. package/dist/lib/redact.js.map +1 -1
  30. package/dist/lib/trigger-detection.d.ts.map +1 -1
  31. package/dist/lib/trigger-detection.js +12 -1
  32. package/dist/lib/trigger-detection.js.map +1 -1
  33. package/dist/providers/exa/adapter.d.ts.map +1 -1
  34. package/dist/providers/exa/adapter.js +44 -21
  35. package/dist/providers/exa/adapter.js.map +1 -1
  36. package/dist/providers/jina/adapter.d.ts +42 -0
  37. package/dist/providers/jina/adapter.d.ts.map +1 -0
  38. package/dist/providers/jina/adapter.js +248 -0
  39. package/dist/providers/jina/adapter.js.map +1 -0
  40. package/dist/providers/jina/client.d.ts +46 -0
  41. package/dist/providers/jina/client.d.ts.map +1 -0
  42. package/dist/providers/jina/client.js +203 -0
  43. package/dist/providers/jina/client.js.map +1 -0
  44. package/dist/providers/jina/credentials.d.ts +14 -0
  45. package/dist/providers/jina/credentials.d.ts.map +1 -0
  46. package/dist/providers/jina/credentials.js +24 -0
  47. package/dist/providers/jina/credentials.js.map +1 -0
  48. package/dist/providers/jina/diagnostics.d.ts +13 -0
  49. package/dist/providers/jina/diagnostics.d.ts.map +1 -0
  50. package/dist/providers/jina/diagnostics.js +36 -0
  51. package/dist/providers/jina/diagnostics.js.map +1 -0
  52. package/dist/providers/parallel/adapter.d.ts +43 -0
  53. package/dist/providers/parallel/adapter.d.ts.map +1 -0
  54. package/dist/providers/parallel/adapter.js +270 -0
  55. package/dist/providers/parallel/adapter.js.map +1 -0
  56. package/dist/providers/parallel/client.d.ts +46 -0
  57. package/dist/providers/parallel/client.d.ts.map +1 -0
  58. package/dist/providers/parallel/client.js +127 -0
  59. package/dist/providers/parallel/client.js.map +1 -0
  60. package/dist/providers/parallel/credentials.d.ts +9 -0
  61. package/dist/providers/parallel/credentials.d.ts.map +1 -0
  62. package/dist/providers/parallel/credentials.js +26 -0
  63. package/dist/providers/parallel/credentials.js.map +1 -0
  64. package/dist/providers/parallel/diagnostics.d.ts +13 -0
  65. package/dist/providers/parallel/diagnostics.d.ts.map +1 -0
  66. package/dist/providers/parallel/diagnostics.js +36 -0
  67. package/dist/providers/parallel/diagnostics.js.map +1 -0
  68. package/dist/providers/perplexity/adapter.d.ts +56 -0
  69. package/dist/providers/perplexity/adapter.d.ts.map +1 -0
  70. package/dist/providers/perplexity/adapter.js +238 -0
  71. package/dist/providers/perplexity/adapter.js.map +1 -0
  72. package/dist/providers/perplexity/client.d.ts +56 -0
  73. package/dist/providers/perplexity/client.d.ts.map +1 -0
  74. package/dist/providers/perplexity/client.js +156 -0
  75. package/dist/providers/perplexity/client.js.map +1 -0
  76. package/dist/providers/perplexity/credentials.d.ts +9 -0
  77. package/dist/providers/perplexity/credentials.d.ts.map +1 -0
  78. package/dist/providers/perplexity/credentials.js +26 -0
  79. package/dist/providers/perplexity/credentials.js.map +1 -0
  80. package/dist/providers/perplexity/diagnostics.d.ts +13 -0
  81. package/dist/providers/perplexity/diagnostics.d.ts.map +1 -0
  82. package/dist/providers/perplexity/diagnostics.js +36 -0
  83. package/dist/providers/perplexity/diagnostics.js.map +1 -0
  84. package/dist/providers/registry.d.ts +2 -2
  85. package/dist/providers/registry.d.ts.map +1 -1
  86. package/dist/providers/registry.js +8 -2
  87. package/dist/providers/registry.js.map +1 -1
  88. package/dist/providers/types.d.ts +1 -1
  89. package/dist/providers/types.d.ts.map +1 -1
  90. package/dist/providers/types.js +11 -1
  91. package/dist/providers/types.js.map +1 -1
  92. package/package.json +1 -1
@@ -0,0 +1,270 @@
1
+ /**
2
+ * Parallel AI Provider Adapter.
3
+ *
4
+ * Implements Search, Research, and Diagnostics capabilities for Parallel AI.
5
+ *
6
+ * Field mapping (Parallel API → Provider-neutral):
7
+ * results[].title -> title
8
+ * results[].url -> url
9
+ * results[].excerpts[] -> summary (joined with double newlines)
10
+ * results[].publish_date -> date
11
+ *
12
+ * Reader (Extract API):
13
+ * results[].full_content -> content (fallback: excerpts joined)
14
+ * results[].title -> title
15
+ * results[].url -> finalUrl
16
+ *
17
+ * Control mapping (SearchControls → Parallel-native API params):
18
+ * topic -> appended to query string (Parallel has no native topic field)
19
+ * type -> REJECTED (UnsupportedOptionError)
20
+ * location -> REJECTED (UnsupportedOptionError)
21
+ * domain -> REJECTED (UnsupportedOptionError; API does not accept it)
22
+ * recency -> REJECTED (UnsupportedOptionError; API does not accept it)
23
+ */
24
+ import crypto from "node:crypto";
25
+ import { decodeResearchResult } from "../../capabilities/research.js";
26
+ import { decodeReaderFetchResult } from "../../capabilities/reader.js";
27
+ import { ApiError, AuthError, ConfigurationError, NetworkError, QuotaError, TimeoutError, UnsupportedOptionError, ValidationError, } from "../../lib/errors.js";
28
+ import { requireParallelApiKey, isParallelConfigured } from "./credentials.js";
29
+ import { fetchParallelSearch, fetchParallelExtract, } from "./client.js";
30
+ import { createParallelDiagnosticsCapability } from "./diagnostics.js";
31
+ function credentialFingerprint(apiKey) {
32
+ return crypto.createHash("sha256").update(apiKey).digest("hex");
33
+ }
34
+ /**
35
+ * Normalize a Provider failure with sanitized messages. Raw response
36
+ * bodies never cross the adapter boundary. Same pattern as the Tavily
37
+ * adapter's `normalizeTavilyError`.
38
+ */
39
+ function normalizeParallelError(error) {
40
+ if (error instanceof QuotaError ||
41
+ error instanceof ValidationError ||
42
+ error instanceof UnsupportedOptionError ||
43
+ error instanceof ConfigurationError ||
44
+ error instanceof AuthError ||
45
+ error instanceof ApiError ||
46
+ error instanceof NetworkError ||
47
+ error instanceof TimeoutError) {
48
+ return error;
49
+ }
50
+ return new ApiError(`Parallel AI request failed: ${error instanceof Error ? error.message : String(error)}`, 500);
51
+ }
52
+ function assertHttpUrl(url) {
53
+ if (typeof url !== "string" || url.length === 0) {
54
+ throw new ValidationError("Parallel reader URL must be a non-empty string");
55
+ }
56
+ if (!/^https?:\/\//.test(url)) {
57
+ throw new ValidationError("URL must start with http:// or https://");
58
+ }
59
+ }
60
+ export class ParallelAdapter {
61
+ context;
62
+ id = "parallel";
63
+ search;
64
+ research;
65
+ reader;
66
+ diagnostics;
67
+ constructor(context, deps = {}) {
68
+ this.context = context;
69
+ const transport = deps.transport;
70
+ const env = context.env;
71
+ this.search = {
72
+ validate(request) {
73
+ if (!request.query || request.query.trim().length === 0) {
74
+ throw new ValidationError("Search query must not be empty");
75
+ }
76
+ if (request.controls?.type !== undefined) {
77
+ throw new UnsupportedOptionError("parallel", "search", "type");
78
+ }
79
+ if (request.controls?.location !== undefined) {
80
+ throw new UnsupportedOptionError("parallel", "search", "location");
81
+ }
82
+ if (request.controls?.domain !== undefined) {
83
+ throw new UnsupportedOptionError("parallel", "search", "domain");
84
+ }
85
+ if (request.controls?.recency !== undefined) {
86
+ throw new UnsupportedOptionError("parallel", "search", "recency");
87
+ }
88
+ if (request.controls?.contentSize !== undefined) {
89
+ throw new UnsupportedOptionError("parallel", "search", "contentSize");
90
+ }
91
+ },
92
+ cacheIdentity(request) {
93
+ const apiKey = requireParallelApiKey(env);
94
+ return {
95
+ provider: "parallel",
96
+ capability: "search",
97
+ credentialFingerprint: credentialFingerprint(apiKey),
98
+ request: {
99
+ query: request.query.trim(),
100
+ controls: request.controls,
101
+ },
102
+ };
103
+ },
104
+ async invoke(request) {
105
+ const apiKey = requireParallelApiKey(env);
106
+ let query = request.query.trim();
107
+ // Parallel AI has no native topic parameter, so we append it to
108
+ // the query string to bias results.
109
+ if (request.controls?.topic && request.controls.topic !== "general") {
110
+ query = `${query} ${request.controls.topic}`;
111
+ }
112
+ const params = {};
113
+ try {
114
+ const response = await fetchParallelSearch(apiKey, query, params, transport);
115
+ const results = response.results || [];
116
+ return results.map((item) => ({
117
+ title: item.title || "Untitled",
118
+ url: item.url || "",
119
+ summary: item.excerpts?.join("\n\n") || "",
120
+ source: "Parallel AI",
121
+ date: item.publish_date || undefined,
122
+ }));
123
+ }
124
+ catch (error) {
125
+ throw normalizeParallelError(error);
126
+ }
127
+ },
128
+ };
129
+ this.research = {
130
+ run: {
131
+ kind: "research-fetch",
132
+ validate(request) {
133
+ if (!request.query || request.query.trim().length === 0) {
134
+ throw new ValidationError("Research query must not be empty");
135
+ }
136
+ for (const option of [
137
+ "model",
138
+ "outputLength",
139
+ "citationFormat",
140
+ "domain",
141
+ ]) {
142
+ if (request[option] !== undefined) {
143
+ throw new UnsupportedOptionError("parallel", "research", option);
144
+ }
145
+ }
146
+ },
147
+ cacheIdentity(request) {
148
+ const apiKey = requireParallelApiKey(env);
149
+ return {
150
+ provider: "parallel",
151
+ capability: "research",
152
+ operation: "research-fetch",
153
+ credentialFingerprint: credentialFingerprint(apiKey),
154
+ request,
155
+ };
156
+ },
157
+ decodeCached: decodeResearchResult,
158
+ async invoke(request) {
159
+ const apiKey = requireParallelApiKey(env);
160
+ const query = request.query.trim();
161
+ try {
162
+ const response = await fetchParallelSearch(apiKey, query, { objective: "deep-research" }, transport);
163
+ const results = response.results || [];
164
+ // Parallel AI does not return a synthesized report field.
165
+ // Build the report from the excerpts of all results.
166
+ const report = results.length > 0
167
+ ? results
168
+ .map((r) => r.excerpts?.join("\n"))
169
+ .filter((text) => typeof text === "string" && text.length > 0)
170
+ .join("\n\n")
171
+ : "No research findings available.";
172
+ return {
173
+ schemaVersion: 1,
174
+ query,
175
+ model: "auto",
176
+ report,
177
+ sources: results
178
+ .filter((r) => r.url)
179
+ .map((r) => ({
180
+ title: r.title || "Untitled",
181
+ url: r.url,
182
+ })),
183
+ };
184
+ }
185
+ catch (error) {
186
+ throw normalizeParallelError(error);
187
+ }
188
+ },
189
+ },
190
+ };
191
+ this.reader = {
192
+ fetch: {
193
+ kind: "reader-fetch",
194
+ validate(request) {
195
+ assertHttpUrl(request.url);
196
+ // Parallel Extract always returns markdown content.
197
+ if (request.format === "text") {
198
+ throw new UnsupportedOptionError("parallel", "reader", "format");
199
+ }
200
+ for (const key of [
201
+ "withLinksSummary",
202
+ "noGfm",
203
+ "keepImgDataUrl",
204
+ "withImagesSummary",
205
+ "retainImages",
206
+ ]) {
207
+ if (request[key] === true) {
208
+ throw new UnsupportedOptionError("parallel", "reader", key);
209
+ }
210
+ }
211
+ },
212
+ cacheIdentity(request) {
213
+ const apiKey = requireParallelApiKey(env);
214
+ return {
215
+ provider: "parallel",
216
+ capability: "reader",
217
+ operation: "reader-fetch",
218
+ credentialFingerprint: credentialFingerprint(apiKey),
219
+ request,
220
+ legacyCandidates: [],
221
+ };
222
+ },
223
+ decodeCached: decodeReaderFetchResult,
224
+ async invoke(request) {
225
+ const apiKey = requireParallelApiKey(env);
226
+ try {
227
+ const response = await fetchParallelExtract(apiKey, request.url, transport);
228
+ // Check for extraction errors for the requested URL
229
+ if (response.errors && response.errors.length > 0) {
230
+ for (const err of response.errors) {
231
+ if (err.url === request.url) {
232
+ throw new ApiError(`Parallel AI extract failed for URL (${err.error_type || "unknown"})`, err.http_status_code || 422);
233
+ }
234
+ }
235
+ }
236
+ const result = response.results?.[0];
237
+ const content = result?.full_content || result?.excerpts?.join("\n\n") || "";
238
+ if (content.length === 0) {
239
+ throw new ApiError("Parallel AI extract returned no content", 422);
240
+ }
241
+ return {
242
+ schemaVersion: 1,
243
+ url: request.url,
244
+ finalUrl: result?.url || request.url,
245
+ title: result?.title || null,
246
+ content,
247
+ contentFormat: "markdown",
248
+ };
249
+ }
250
+ catch (error) {
251
+ throw normalizeParallelError(error);
252
+ }
253
+ },
254
+ },
255
+ };
256
+ this.diagnostics = createParallelDiagnosticsCapability({ env, transport });
257
+ }
258
+ }
259
+ export function createParallelDescriptor() {
260
+ return {
261
+ id: "parallel",
262
+ credentialEnvVars: ["PARALLEL_API_KEY"],
263
+ isConfigured: isParallelConfigured,
264
+ capabilities() {
265
+ return new Set(["search", "research", "reader", "diagnostics"]);
266
+ },
267
+ create: (context) => new ParallelAdapter(context),
268
+ };
269
+ }
270
+ //# sourceMappingURL=adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../../src/providers/parallel/adapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Parallel AI direct HTTP transport.
3
+ *
4
+ * Performs direct HTTP requests against Parallel AI API endpoints.
5
+ */
6
+ import type { ProviderQuotaFetchResponse } from "../types.js";
7
+ export interface ParallelTransportDeps {
8
+ readonly fetch?: (input: string, init: Record<string, unknown>) => Promise<ProviderQuotaFetchResponse>;
9
+ readonly setTimeout?: typeof setTimeout;
10
+ readonly clearTimeout?: typeof clearTimeout;
11
+ readonly env?: NodeJS.ProcessEnv;
12
+ }
13
+ export interface ParallelSearchParams {
14
+ readonly objective?: string;
15
+ }
16
+ export interface ParallelSearchResultItem {
17
+ readonly title?: string;
18
+ readonly url?: string;
19
+ readonly excerpts?: readonly string[];
20
+ readonly publish_date?: string | null;
21
+ }
22
+ export interface ParallelSearchResponse {
23
+ readonly search_id?: string;
24
+ readonly results?: readonly ParallelSearchResultItem[];
25
+ readonly usage?: readonly unknown[];
26
+ readonly session_id?: string;
27
+ }
28
+ export declare function fetchParallelSearch(apiKey: string, query: string, params?: ParallelSearchParams, deps?: ParallelTransportDeps): Promise<ParallelSearchResponse>;
29
+ export interface ParallelExtractResultItem {
30
+ readonly url?: string;
31
+ readonly title?: string;
32
+ readonly publish_date?: string | null;
33
+ readonly excerpts?: readonly string[];
34
+ readonly full_content?: string;
35
+ }
36
+ export interface ParallelExtractErrorEntry {
37
+ readonly url?: string;
38
+ readonly error_type?: string;
39
+ readonly http_status_code?: number;
40
+ }
41
+ export interface ParallelExtractResponse {
42
+ readonly results?: readonly ParallelExtractResultItem[];
43
+ readonly errors?: readonly ParallelExtractErrorEntry[];
44
+ }
45
+ export declare function fetchParallelExtract(apiKey: string, targetUrl: string, deps?: ParallelTransportDeps): Promise<ParallelExtractResponse>;
46
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/providers/parallel/client.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAC;AAW9D,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,KAAK,CAAC,EAAE,CACf,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC1B,OAAO,CAAC,0BAA0B,CAAC,CAAC;IACzC,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,UAAU,CAAC;IACxC,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,YAAY,CAAC;IAC5C,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CAClC;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACvC;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,wBAAwB,EAAE,CAAC;IACvD,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,OAAO,EAAE,CAAC;IACpC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B;AA0BD,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,MAAM,GAAE,oBAAyB,EACjC,IAAI,GAAE,qBAA0B,GAC/B,OAAO,CAAC,sBAAsB,CAAC,CAoDjC;AAMD,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;CACpC;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,yBAAyB,EAAE,CAAC;IACxD,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,yBAAyB,EAAE,CAAC;CACxD;AAED,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,IAAI,GAAE,qBAA0B,GAC/B,OAAO,CAAC,uBAAuB,CAAC,CA+ClC"}
@@ -0,0 +1,127 @@
1
+ /**
2
+ * Parallel AI direct HTTP transport.
3
+ *
4
+ * Performs direct HTTP requests against Parallel AI API endpoints.
5
+ */
6
+ import { createRequire } from "node:module";
7
+ import { ApiError, AuthError, NetworkError, TimeoutError } from "../../lib/errors.js";
8
+ const require = createRequire(import.meta.url);
9
+ const { version: VERSION } = require("../../../package.json");
10
+ const BASE_URL = "https://api.parallel.ai";
11
+ const DEFAULT_TIMEOUT_MS = 30000;
12
+ const USER_AGENT = `scoutline/${VERSION}`;
13
+ const TIMEOUT_HELP_TEXT = "Try again or increase timeout with PARALLEL_TIMEOUT env var";
14
+ function resolveTimeoutMs(env) {
15
+ const raw = parseInt(env.PARALLEL_TIMEOUT || String(DEFAULT_TIMEOUT_MS), 10);
16
+ return Number.isFinite(raw) && raw > 0 ? raw : DEFAULT_TIMEOUT_MS;
17
+ }
18
+ function mapStatusError(status, timeoutMs) {
19
+ if (status === 401 || status === 403) {
20
+ return new AuthError("Parallel AI authentication failed", "PARALLEL_API_KEY");
21
+ }
22
+ if (status === 408 || status === 504) {
23
+ return new TimeoutError(timeoutMs, TIMEOUT_HELP_TEXT);
24
+ }
25
+ if (status === 429) {
26
+ return new ApiError("Parallel AI rate limit exceeded", 429);
27
+ }
28
+ if (status >= 400 && status < 500) {
29
+ return new ApiError(`Parallel AI API client error (${status})`, status);
30
+ }
31
+ if (status >= 500) {
32
+ return new ApiError(`Parallel AI API server error (${status})`, status);
33
+ }
34
+ return new ApiError(`Parallel AI request failed (${status})`, status);
35
+ }
36
+ export async function fetchParallelSearch(apiKey, query, params = {}, deps = {}) {
37
+ const fetchFn = deps.fetch || globalThis.fetch;
38
+ const setTimer = deps.setTimeout || globalThis.setTimeout;
39
+ const clearTimer = deps.clearTimeout || globalThis.clearTimeout;
40
+ const env = deps.env || process.env;
41
+ const timeoutMs = resolveTimeoutMs(env);
42
+ const url = `${BASE_URL}/v1/search`;
43
+ const body = {
44
+ search_queries: [query],
45
+ };
46
+ if (params.objective) {
47
+ body.objective = params.objective;
48
+ }
49
+ const controller = new AbortController();
50
+ const timer = setTimer(() => controller.abort(), timeoutMs);
51
+ try {
52
+ const response = await fetchFn(url, {
53
+ method: "POST",
54
+ headers: {
55
+ "Content-Type": "application/json",
56
+ "Authorization": `Bearer ${apiKey}`,
57
+ "User-Agent": USER_AGENT,
58
+ },
59
+ body: JSON.stringify(body),
60
+ signal: controller.signal,
61
+ });
62
+ if (!response.ok) {
63
+ throw mapStatusError(response.status, timeoutMs);
64
+ }
65
+ const text = await response.text();
66
+ return JSON.parse(text);
67
+ }
68
+ catch (err) {
69
+ if (err instanceof AuthError || err instanceof ApiError || err instanceof TimeoutError) {
70
+ throw err;
71
+ }
72
+ if (err instanceof SyntaxError) {
73
+ throw new ApiError("Parallel AI returned a malformed JSON response", 500);
74
+ }
75
+ if (err instanceof Error && err.name === "AbortError") {
76
+ throw new TimeoutError(timeoutMs, TIMEOUT_HELP_TEXT);
77
+ }
78
+ throw new NetworkError(`Parallel AI request failed: ${err instanceof Error ? err.message : String(err)}`);
79
+ }
80
+ finally {
81
+ clearTimer(timer);
82
+ }
83
+ }
84
+ export async function fetchParallelExtract(apiKey, targetUrl, deps = {}) {
85
+ const fetchFn = deps.fetch || globalThis.fetch;
86
+ const setTimer = deps.setTimeout || globalThis.setTimeout;
87
+ const clearTimer = deps.clearTimeout || globalThis.clearTimeout;
88
+ const env = deps.env || process.env;
89
+ const timeoutMs = resolveTimeoutMs(env);
90
+ const url = `${BASE_URL}/v1/extract`;
91
+ const body = { urls: [targetUrl] };
92
+ const controller = new AbortController();
93
+ const timer = setTimer(() => controller.abort(), timeoutMs);
94
+ try {
95
+ const response = await fetchFn(url, {
96
+ method: "POST",
97
+ headers: {
98
+ "Content-Type": "application/json",
99
+ "Authorization": `Bearer ${apiKey}`,
100
+ "User-Agent": USER_AGENT,
101
+ },
102
+ body: JSON.stringify(body),
103
+ signal: controller.signal,
104
+ });
105
+ if (!response.ok) {
106
+ throw mapStatusError(response.status, timeoutMs);
107
+ }
108
+ const text = await response.text();
109
+ return JSON.parse(text);
110
+ }
111
+ catch (err) {
112
+ if (err instanceof AuthError || err instanceof ApiError || err instanceof TimeoutError) {
113
+ throw err;
114
+ }
115
+ if (err instanceof SyntaxError) {
116
+ throw new ApiError("Parallel AI returned a malformed JSON response", 500);
117
+ }
118
+ if (err instanceof Error && err.name === "AbortError") {
119
+ throw new TimeoutError(timeoutMs, TIMEOUT_HELP_TEXT);
120
+ }
121
+ throw new NetworkError(`Parallel AI extract failed: ${err instanceof Error ? err.message : String(err)}`);
122
+ }
123
+ finally {
124
+ clearTimer(timer);
125
+ }
126
+ }
127
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../../src/providers/parallel/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Parallel AI credential resolution.
3
+ *
4
+ * Single source of truth for the Parallel AI API key (`PARALLEL_API_KEY`).
5
+ */
6
+ export declare function resolveParallelApiKey(env: NodeJS.ProcessEnv): string | undefined;
7
+ export declare function requireParallelApiKey(env: NodeJS.ProcessEnv): string;
8
+ export declare function isParallelConfigured(env: NodeJS.ProcessEnv): boolean;
9
+ //# sourceMappingURL=credentials.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../../../src/providers/parallel/credentials.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAWH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG,MAAM,GAAG,SAAS,CAEhF;AAED,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG,MAAM,CASpE;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG,OAAO,CAEpE"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Parallel AI credential resolution.
3
+ *
4
+ * Single source of truth for the Parallel AI API key (`PARALLEL_API_KEY`).
5
+ */
6
+ import { ConfigurationError } from "../../lib/errors.js";
7
+ const MISSING_KEY_HELP = 'export PARALLEL_API_KEY="your-parallel-api-key"';
8
+ function pickNonBlank(raw) {
9
+ if (typeof raw !== "string")
10
+ return undefined;
11
+ return raw.trim().length > 0 ? raw : undefined;
12
+ }
13
+ export function resolveParallelApiKey(env) {
14
+ return pickNonBlank(env.PARALLEL_API_KEY);
15
+ }
16
+ export function requireParallelApiKey(env) {
17
+ const key = resolveParallelApiKey(env);
18
+ if (key === undefined) {
19
+ throw new ConfigurationError("PARALLEL_API_KEY environment variable is required", MISSING_KEY_HELP);
20
+ }
21
+ return key;
22
+ }
23
+ export function isParallelConfigured(env) {
24
+ return resolveParallelApiKey(env) !== undefined;
25
+ }
26
+ //# sourceMappingURL=credentials.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credentials.js","sourceRoot":"","sources":["../../../src/providers/parallel/credentials.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAEzD,MAAM,gBAAgB,GAAG,iDAAiD,CAAC;AAE3E,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,MAAM,UAAU,qBAAqB,CAAC,GAAsB;IAC1D,OAAO,YAAY,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;AAC5C,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,GAAsB;IAC1D,MAAM,GAAG,GAAG,qBAAqB,CAAC,GAAG,CAAC,CAAC;IACvC,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;QACtB,MAAM,IAAI,kBAAkB,CAC1B,mDAAmD,EACnD,gBAAgB,CACjB,CAAC;IACJ,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,GAAsB;IACzD,OAAO,qBAAqB,CAAC,GAAG,CAAC,KAAK,SAAS,CAAC;AAClD,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Parallel AI Diagnostics Capability.
3
+ *
4
+ * Probes Parallel AI connectivity with a lightweight probe request.
5
+ */
6
+ import type { DiagnosticsCapability } from "../../capabilities/diagnostics.js";
7
+ import { type ParallelTransportDeps } from "./client.js";
8
+ export interface ParallelDiagnosticsCapabilityOptions {
9
+ readonly env: NodeJS.ProcessEnv;
10
+ readonly transport?: ParallelTransportDeps;
11
+ }
12
+ export declare function createParallelDiagnosticsCapability(options: ParallelDiagnosticsCapabilityOptions): DiagnosticsCapability;
13
+ //# sourceMappingURL=diagnostics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnostics.d.ts","sourceRoot":"","sources":["../../../src/providers/parallel/diagnostics.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,qBAAqB,EAAqB,MAAM,mCAAmC,CAAC;AAUlG,OAAO,EAAuB,KAAK,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAgB9E,MAAM,WAAW,oCAAoC;IACnD,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;IAChC,QAAQ,CAAC,SAAS,CAAC,EAAE,qBAAqB,CAAC;CAC5C;AAED,wBAAgB,mCAAmC,CACjD,OAAO,EAAE,oCAAoC,GAC5C,qBAAqB,CAavB"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Parallel AI Diagnostics Capability.
3
+ *
4
+ * Probes Parallel AI connectivity with a lightweight probe request.
5
+ */
6
+ import { ApiError, AuthError, ConfigurationError, NetworkError, QuotaError, TimeoutError, } from "../../lib/errors.js";
7
+ import { requireParallelApiKey } from "./credentials.js";
8
+ import { fetchParallelSearch } from "./client.js";
9
+ function normalizeProbeError(error) {
10
+ if (error instanceof AuthError ||
11
+ error instanceof QuotaError ||
12
+ error instanceof ApiError ||
13
+ error instanceof NetworkError ||
14
+ error instanceof TimeoutError ||
15
+ error instanceof ConfigurationError) {
16
+ return error;
17
+ }
18
+ return new ApiError("Parallel AI diagnostics probe failed", 500);
19
+ }
20
+ export function createParallelDiagnosticsCapability(options) {
21
+ const { env, transport } = options;
22
+ return {
23
+ async invoke(diagOptions) {
24
+ if (!diagOptions.probe)
25
+ return;
26
+ const apiKey = requireParallelApiKey(env);
27
+ try {
28
+ await fetchParallelSearch(apiKey, "scoutline-doctor-probe", {}, transport);
29
+ }
30
+ catch (error) {
31
+ throw normalizeProbeError(error);
32
+ }
33
+ },
34
+ };
35
+ }
36
+ //# sourceMappingURL=diagnostics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnostics.js","sourceRoot":"","sources":["../../../src/providers/parallel/diagnostics.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EACL,QAAQ,EACR,SAAS,EACT,kBAAkB,EAClB,YAAY,EACZ,UAAU,EACV,YAAY,GACb,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAA8B,MAAM,aAAa,CAAC;AAE9E,SAAS,mBAAmB,CAAC,KAAc;IACzC,IACE,KAAK,YAAY,SAAS;QAC1B,KAAK,YAAY,UAAU;QAC3B,KAAK,YAAY,QAAQ;QACzB,KAAK,YAAY,YAAY;QAC7B,KAAK,YAAY,YAAY;QAC7B,KAAK,YAAY,kBAAkB,EACnC,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,IAAI,QAAQ,CAAC,sCAAsC,EAAE,GAAG,CAAC,CAAC;AACnE,CAAC;AAOD,MAAM,UAAU,mCAAmC,CACjD,OAA6C;IAE7C,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC;IACnC,OAAO;QACL,KAAK,CAAC,MAAM,CAAC,WAA8B;YACzC,IAAI,CAAC,WAAW,CAAC,KAAK;gBAAE,OAAO;YAC/B,MAAM,MAAM,GAAG,qBAAqB,CAAC,GAAG,CAAC,CAAC;YAC1C,IAAI,CAAC;gBACH,MAAM,mBAAmB,CAAC,MAAM,EAAE,wBAAwB,EAAE,EAAE,EAAE,SAAS,CAAC,CAAC;YAC7E,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,mBAAmB,CAAC,KAAK,CAAC,CAAC;YACnC,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Perplexity Provider Adapter.
3
+ *
4
+ * Implements Search, Research, and Diagnostics capabilities for the
5
+ * Perplexity API.
6
+ *
7
+ * Search uses the dedicated Search API (POST /search) which returns
8
+ * structured results with titles, URLs, snippets, and dates — far richer
9
+ * than mapping chat completions to citations.
10
+ *
11
+ * Research uses the Sonar Chat Completions endpoint with the
12
+ * `sonar-deep-research` model, which is designed for comprehensive
13
+ * report synthesis. The response includes `search_results[]` with
14
+ * structured source data (title, url, date, snippet).
15
+ *
16
+ * Reader is intentionally omitted: Perplexity does not offer a
17
+ * dedicated webpage extraction API.
18
+ *
19
+ * Field mapping:
20
+ * Search (/search):
21
+ * results[].title -> title
22
+ * results[].url -> url
23
+ * results[].snippet -> summary
24
+ * results[].date -> date
25
+ * Research (/chat/completions):
26
+ * choices[0].message.content -> report
27
+ * search_results[].title/url -> sources[]
28
+ * citations[] (fallback) -> sources[]
29
+ *
30
+ * Control mapping (SearchControls → Search API params):
31
+ * domain -> search_domain_filter: [domain]
32
+ * recency -> search_recency_filter (oneDay→"day", oneWeek→"week",
33
+ * oneMonth→"month", oneYear→"year", noLimit→omit)
34
+ * contentSize -> search_context_size (medium→"medium", high→"high")
35
+ * type -> REJECTED (UnsupportedOptionError)
36
+ * location -> REJECTED (UnsupportedOptionError)
37
+ * topic -> REJECTED (UnsupportedOptionError)
38
+ */
39
+ import type { ProviderAdapter, ProviderContext, ProviderDescriptor, ProviderId } from "../types.js";
40
+ import type { SearchCapability } from "../../capabilities/search.js";
41
+ import type { ResearchCapability } from "../../capabilities/research.js";
42
+ import type { DiagnosticsCapability } from "../../capabilities/diagnostics.js";
43
+ import { type PerplexityTransportDeps } from "./client.js";
44
+ export interface PerplexityAdapterDependencies {
45
+ readonly transport?: PerplexityTransportDeps;
46
+ }
47
+ export declare class PerplexityAdapter implements ProviderAdapter {
48
+ private readonly context;
49
+ readonly id: ProviderId;
50
+ readonly search: SearchCapability;
51
+ readonly research: ResearchCapability;
52
+ readonly diagnostics: DiagnosticsCapability;
53
+ constructor(context: ProviderContext, deps?: PerplexityAdapterDependencies);
54
+ }
55
+ export declare function createPerplexityDescriptor(): ProviderDescriptor;
56
+ //# sourceMappingURL=adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../src/providers/perplexity/adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAGH,OAAO,KAAK,EACV,eAAe,EAEf,eAAe,EACf,kBAAkB,EAClB,UAAU,EACX,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAIV,gBAAgB,EAGjB,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EACV,kBAAkB,EAGnB,MAAM,gCAAgC,CAAC;AAExC,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,mCAAmC,CAAC;AAY/E,OAAO,EAIL,KAAK,uBAAuB,EAC7B,MAAM,aAAa,CAAC;AAoErB,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,CAAC,SAAS,CAAC,EAAE,uBAAuB,CAAC;CAC9C;AAED,qBAAa,iBAAkB,YAAW,eAAe;IAOrD,OAAO,CAAC,QAAQ,CAAC,OAAO;IAN1B,QAAQ,CAAC,EAAE,EAAE,UAAU,CAAgB;IACvC,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAC;IAClC,QAAQ,CAAC,QAAQ,EAAE,kBAAkB,CAAC;IACtC,QAAQ,CAAC,WAAW,EAAE,qBAAqB,CAAC;IAE5C,YACmB,OAAO,EAAE,eAAe,EACzC,IAAI,GAAE,6BAAkC,EAyIzC;CACF;AAED,wBAAgB,0BAA0B,IAAI,kBAAkB,CAU/D"}