@oh-my-pi/pi-coding-agent 16.1.13 → 16.1.15
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/CHANGELOG.md +48 -0
- package/dist/cli.js +5615 -2833
- package/dist/types/advisor/runtime.d.ts +3 -0
- package/dist/types/config/settings-schema.d.ts +64 -14
- package/dist/types/eval/__tests__/julia-prelude.test.d.ts +1 -0
- package/dist/types/eval/backend-helpers.d.ts +23 -0
- package/dist/types/eval/executor-base.d.ts +118 -0
- package/dist/types/eval/index.d.ts +2 -0
- package/dist/types/eval/jl/executor.d.ts +44 -0
- package/dist/types/eval/jl/index.d.ts +11 -0
- package/dist/types/eval/jl/kernel.d.ts +28 -0
- package/dist/types/eval/jl/prelude.d.ts +1 -0
- package/dist/types/eval/jl/runtime.d.ts +22 -0
- package/dist/types/eval/kernel-base.d.ts +105 -0
- package/dist/types/eval/py/kernel.d.ts +3 -61
- package/dist/types/eval/rb/executor.d.ts +77 -0
- package/dist/types/eval/rb/index.d.ts +11 -0
- package/dist/types/eval/rb/kernel.d.ts +31 -0
- package/dist/types/eval/rb/prelude.d.ts +1 -0
- package/dist/types/eval/rb/runtime.d.ts +23 -0
- package/dist/types/eval/runtime-env.d.ts +24 -0
- package/dist/types/eval/types.d.ts +3 -3
- package/dist/types/export/share.d.ts +8 -1
- package/dist/types/extensibility/extensions/runner.d.ts +2 -15
- package/dist/types/extensibility/hooks/loader.d.ts +1 -25
- package/dist/types/extensibility/session-handler-types.d.ts +23 -0
- package/dist/types/jsonrpc/message-framing.d.ts +35 -0
- package/dist/types/mcp/transports/stdio.d.ts +12 -1
- package/dist/types/mnemopi/embed-client.d.ts +7 -24
- package/dist/types/modes/components/chat-transcript-builder.d.ts +1 -1
- package/dist/types/modes/components/custom-editor.d.ts +11 -0
- package/dist/types/modes/components/selector-helpers.d.ts +53 -0
- package/dist/types/modes/components/status-line/context-thresholds.d.ts +4 -3
- package/dist/types/modes/components/status-line/types.d.ts +1 -0
- package/dist/types/modes/interactive-mode.d.ts +0 -2
- package/dist/types/modes/theme/theme.d.ts +8 -1
- package/dist/types/modes/types.d.ts +0 -2
- package/dist/types/modes/utils/copy-targets.d.ts +1 -1
- package/dist/types/modes/utils/interactive-context-helpers.d.ts +14 -0
- package/dist/types/modes/utils/transcript-render-helpers.d.ts +54 -0
- package/dist/types/sdk.d.ts +1 -1
- package/dist/types/secrets/obfuscator.d.ts +3 -3
- package/dist/types/session/agent-session.d.ts +2 -2
- package/dist/types/stt/asr-client.d.ts +3 -29
- package/dist/types/subprocess/worker-client.d.ts +149 -0
- package/dist/types/subprocess/worker-runtime.d.ts +107 -0
- package/dist/types/tiny/title-client.d.ts +14 -34
- package/dist/types/tools/eval-backends.d.ts +6 -3
- package/dist/types/tools/eval-render.d.ts +6 -5
- package/dist/types/tools/eval.d.ts +13 -15
- package/dist/types/tools/index.d.ts +3 -3
- package/dist/types/tts/tts-client.d.ts +3 -28
- package/dist/types/tui/code-cell.d.ts +7 -0
- package/dist/types/utils/file-display-mode.d.ts +1 -1
- package/dist/types/utils/shell-snapshot.d.ts +10 -0
- package/dist/types/web/parallel.d.ts +6 -0
- package/dist/types/web/search/providers/perplexity.d.ts +17 -3
- package/package.json +12 -12
- package/src/advisor/__tests__/advisor.test.ts +114 -0
- package/src/advisor/runtime.ts +129 -1
- package/src/config/model-registry.ts +12 -4
- package/src/config/settings-schema.ts +74 -18
- package/src/config/settings.ts +5 -0
- package/src/dap/client.ts +13 -107
- package/src/eval/__tests__/julia-prelude.test.ts +77 -0
- package/src/eval/backend-helpers.ts +48 -0
- package/src/eval/executor-base.ts +425 -0
- package/src/eval/index.ts +2 -0
- package/src/eval/jl/executor.ts +540 -0
- package/src/eval/jl/index.ts +54 -0
- package/src/eval/jl/kernel.ts +235 -0
- package/src/eval/jl/prelude.jl +930 -0
- package/src/eval/jl/prelude.ts +3 -0
- package/src/eval/jl/runner.jl +634 -0
- package/src/eval/jl/runtime.ts +118 -0
- package/src/eval/js/index.ts +3 -14
- package/src/eval/kernel-base.ts +569 -0
- package/src/eval/py/executor.ts +43 -252
- package/src/eval/py/index.ts +9 -20
- package/src/eval/py/kernel.ts +29 -544
- package/src/eval/rb/executor.ts +504 -0
- package/src/eval/rb/index.ts +54 -0
- package/src/eval/rb/kernel.ts +230 -0
- package/src/eval/rb/prelude.rb +721 -0
- package/src/eval/rb/prelude.ts +3 -0
- package/src/eval/rb/runner.rb +474 -0
- package/src/eval/rb/runtime.ts +132 -0
- package/src/eval/runtime-env.ts +104 -0
- package/src/eval/types.ts +3 -3
- package/src/exec/bash-executor.ts +44 -0
- package/src/export/share.ts +51 -28
- package/src/extensibility/extensions/runner.ts +4 -11
- package/src/extensibility/hooks/loader.ts +3 -21
- package/src/extensibility/session-handler-types.ts +21 -0
- package/src/internal-urls/docs-index.generated.txt +1 -1
- package/src/jsonrpc/message-framing.ts +142 -0
- package/src/lsp/client.ts +13 -109
- package/src/mcp/transports/stdio.ts +20 -4
- package/src/mnemopi/embed-client.ts +43 -198
- package/src/modes/components/agent-dashboard.ts +17 -40
- package/src/modes/components/chat-transcript-builder.ts +18 -102
- package/src/modes/components/custom-editor.test.ts +22 -0
- package/src/modes/components/custom-editor.ts +29 -1
- package/src/modes/components/extensions/extension-dashboard.ts +4 -13
- package/src/modes/components/extensions/extension-list.ts +16 -44
- package/src/modes/components/footer.ts +4 -3
- package/src/modes/components/history-search.ts +4 -16
- package/src/modes/components/selector-helpers.ts +129 -0
- package/src/modes/components/settings-selector.ts +7 -5
- package/src/modes/components/status-line/component.ts +5 -1
- package/src/modes/components/status-line/context-thresholds.ts +11 -3
- package/src/modes/components/status-line/segments.ts +1 -1
- package/src/modes/components/status-line/types.ts +1 -0
- package/src/modes/components/tree-selector.ts +13 -18
- package/src/modes/controllers/command-controller.ts +1 -0
- package/src/modes/controllers/event-controller.ts +3 -9
- package/src/modes/controllers/input-controller.ts +32 -54
- package/src/modes/interactive-mode.ts +5 -7
- package/src/modes/theme/theme.ts +35 -0
- package/src/modes/types.ts +0 -2
- package/src/modes/utils/copy-targets.ts +3 -2
- package/src/modes/utils/interactive-context-helpers.ts +27 -0
- package/src/modes/utils/transcript-render-helpers.ts +157 -0
- package/src/modes/utils/ui-helpers.ts +21 -126
- package/src/prompts/system/system-prompt.md +5 -5
- package/src/prompts/tools/bash.md +2 -3
- package/src/prompts/tools/eval.md +6 -4
- package/src/prompts/tools/find.md +0 -4
- package/src/prompts/tools/read.md +1 -2
- package/src/prompts/tools/replace.md +1 -1
- package/src/sdk.ts +13 -7
- package/src/secrets/obfuscator.ts +3 -9
- package/src/session/agent-session.ts +42 -9
- package/src/slash-commands/builtin-registry.ts +2 -1
- package/src/stt/asr-client.ts +35 -215
- package/src/stt/asr-worker.ts +29 -181
- package/src/subprocess/worker-client.ts +297 -0
- package/src/subprocess/worker-runtime.ts +277 -0
- package/src/task/executor.ts +4 -4
- package/src/tiny/title-client.ts +53 -219
- package/src/tiny/worker.ts +29 -180
- package/src/tools/eval-backends.ts +10 -3
- package/src/tools/eval-render.ts +17 -8
- package/src/tools/eval.ts +187 -22
- package/src/tools/index.ts +51 -28
- package/src/tts/tts-client.ts +38 -206
- package/src/tts/tts-worker.ts +23 -97
- package/src/tui/code-cell.ts +12 -1
- package/src/utils/file-display-mode.ts +2 -3
- package/src/utils/shell-snapshot.ts +63 -1
- package/src/web/parallel.ts +43 -42
- package/src/web/search/providers/parallel.ts +10 -99
- package/src/web/search/providers/perplexity.ts +18 -6
package/src/web/parallel.ts
CHANGED
|
@@ -3,9 +3,9 @@ import type { AgentStorage } from "../session/agent-storage";
|
|
|
3
3
|
import { findCredential, withHardTimeout } from "./search/providers/utils";
|
|
4
4
|
|
|
5
5
|
const PARALLEL_API_URL = "https://api.parallel.ai";
|
|
6
|
-
const PARALLEL_SEARCH_URL = `${PARALLEL_API_URL}/v1beta/search`;
|
|
6
|
+
export const PARALLEL_SEARCH_URL = `${PARALLEL_API_URL}/v1beta/search`;
|
|
7
7
|
const PARALLEL_EXTRACT_URL = `${PARALLEL_API_URL}/v1beta/extract`;
|
|
8
|
-
const PARALLEL_BETA_HEADER = "search-extract-2025-10-10";
|
|
8
|
+
export const PARALLEL_BETA_HEADER = "search-extract-2025-10-10";
|
|
9
9
|
|
|
10
10
|
export interface ParallelUsageItem {
|
|
11
11
|
name?: string;
|
|
@@ -76,22 +76,6 @@ export class ParallelApiError extends Error {
|
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
-
export function findParallelApiKey(storage: AgentStorage | null | undefined): string | null {
|
|
80
|
-
return findCredential(storage, getEnvApiKey("parallel"), "parallel");
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
export function getParallelExtractContent(document: ParallelExtractDocument): string {
|
|
84
|
-
const excerptContent = document.excerpts
|
|
85
|
-
.filter(excerpt => excerpt.trim().length > 0)
|
|
86
|
-
.join("\n\n")
|
|
87
|
-
.trim();
|
|
88
|
-
if (excerptContent.length > 0) {
|
|
89
|
-
return excerptContent;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
return document.fullContent?.trim() ?? "";
|
|
93
|
-
}
|
|
94
|
-
|
|
95
79
|
function isObject(value: unknown): value is object {
|
|
96
80
|
return typeof value === "object" && value !== null;
|
|
97
81
|
}
|
|
@@ -148,7 +132,7 @@ function createParallelApiError(statusCode: number, detail?: string): ParallelAp
|
|
|
148
132
|
);
|
|
149
133
|
}
|
|
150
134
|
|
|
151
|
-
function parseParallelErrorResponse(statusCode: number, responseText: string): ParallelApiError {
|
|
135
|
+
export function parseParallelErrorResponse(statusCode: number, responseText: string): ParallelApiError {
|
|
152
136
|
const trimmedResponseText = responseText.trim();
|
|
153
137
|
if (trimmedResponseText.length === 0) {
|
|
154
138
|
return createParallelApiError(statusCode);
|
|
@@ -176,24 +160,6 @@ function getAuthHeaders(apiKey: string): {
|
|
|
176
160
|
};
|
|
177
161
|
}
|
|
178
162
|
|
|
179
|
-
function normalizeSearchMode(mode: ParallelSearchOptions["mode"]): "fast" | "one-shot" {
|
|
180
|
-
return mode === "research" ? "one-shot" : "fast";
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
function parseUsageItems(payload: unknown): ParallelUsageItem[] {
|
|
184
|
-
if (!Array.isArray(payload)) return [];
|
|
185
|
-
|
|
186
|
-
const usageItems: ParallelUsageItem[] = [];
|
|
187
|
-
for (const item of payload) {
|
|
188
|
-
if (!isObject(item)) continue;
|
|
189
|
-
usageItems.push({
|
|
190
|
-
name: getString(item, "name"),
|
|
191
|
-
count: getNumber(item, "count"),
|
|
192
|
-
});
|
|
193
|
-
}
|
|
194
|
-
return usageItems;
|
|
195
|
-
}
|
|
196
|
-
|
|
197
163
|
function parseWarnings(payload: unknown): string[] {
|
|
198
164
|
if (!Array.isArray(payload)) return [];
|
|
199
165
|
|
|
@@ -212,7 +178,24 @@ function parseWarnings(payload: unknown): string[] {
|
|
|
212
178
|
return warnings;
|
|
213
179
|
}
|
|
214
180
|
|
|
215
|
-
function
|
|
181
|
+
function parseUsageItems(payload: unknown): ParallelUsageItem[] {
|
|
182
|
+
if (!Array.isArray(payload)) return [];
|
|
183
|
+
|
|
184
|
+
const usageItems: ParallelUsageItem[] = [];
|
|
185
|
+
for (const item of payload) {
|
|
186
|
+
if (!isObject(item)) continue;
|
|
187
|
+
usageItems.push({
|
|
188
|
+
name: getString(item, "name"),
|
|
189
|
+
count: getNumber(item, "count"),
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
return usageItems;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
export function parseParallelSearchPayload(
|
|
196
|
+
payload: unknown,
|
|
197
|
+
options?: { parseMetadata?: boolean },
|
|
198
|
+
): ParallelSearchResult {
|
|
216
199
|
if (!isObject(payload)) {
|
|
217
200
|
throw new ParallelApiError("Parallel search returned an invalid response payload.");
|
|
218
201
|
}
|
|
@@ -236,14 +219,32 @@ function parseSearchPayload(payload: unknown): ParallelSearchResult {
|
|
|
236
219
|
});
|
|
237
220
|
}
|
|
238
221
|
|
|
222
|
+
const parseMetadata = options?.parseMetadata ?? true;
|
|
223
|
+
|
|
239
224
|
return {
|
|
240
225
|
requestId,
|
|
241
226
|
sources,
|
|
242
|
-
warnings: parseWarnings(getOwnValue(payload, "warnings")),
|
|
243
|
-
usage: parseUsageItems(getOwnValue(payload, "usage")),
|
|
227
|
+
warnings: parseMetadata ? parseWarnings(getOwnValue(payload, "warnings")) : [],
|
|
228
|
+
usage: parseMetadata ? parseUsageItems(getOwnValue(payload, "usage")) : [],
|
|
244
229
|
};
|
|
245
230
|
}
|
|
246
231
|
|
|
232
|
+
export function findParallelApiKey(storage: AgentStorage | null | undefined): string | null {
|
|
233
|
+
return findCredential(storage, getEnvApiKey("parallel"), "parallel");
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
export function getParallelExtractContent(document: ParallelExtractDocument): string {
|
|
237
|
+
const excerptContent = document.excerpts
|
|
238
|
+
.filter(excerpt => excerpt.trim().length > 0)
|
|
239
|
+
.join("\n\n")
|
|
240
|
+
.trim();
|
|
241
|
+
if (excerptContent.length > 0) {
|
|
242
|
+
return excerptContent;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
return document.fullContent?.trim() ?? "";
|
|
246
|
+
}
|
|
247
|
+
|
|
247
248
|
function parseExtractPayload(payload: unknown): ParallelExtractResult {
|
|
248
249
|
if (!isObject(payload)) {
|
|
249
250
|
throw new ParallelApiError("Parallel extract returned an invalid response payload.");
|
|
@@ -304,7 +305,7 @@ export async function searchWithParallel(
|
|
|
304
305
|
body: JSON.stringify({
|
|
305
306
|
objective,
|
|
306
307
|
search_queries: queries,
|
|
307
|
-
mode:
|
|
308
|
+
mode: options.mode === "research" ? "one-shot" : "fast",
|
|
308
309
|
excerpts: {
|
|
309
310
|
max_chars_per_result: options.maxCharsPerResult ?? 10_000,
|
|
310
311
|
},
|
|
@@ -316,7 +317,7 @@ export async function searchWithParallel(
|
|
|
316
317
|
}
|
|
317
318
|
|
|
318
319
|
const payload: unknown = await response.json();
|
|
319
|
-
return
|
|
320
|
+
return parseParallelSearchPayload(payload);
|
|
320
321
|
}
|
|
321
322
|
|
|
322
323
|
export async function extractWithParallel(
|
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
import { type ApiKey, type AuthStorage, type FetchImpl, getEnvApiKey, withAuth } from "@oh-my-pi/pi-ai";
|
|
2
2
|
import type { SearchResponse } from "../../../web/search/types";
|
|
3
3
|
import { SearchProviderError } from "../../../web/search/types";
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
PARALLEL_BETA_HEADER,
|
|
6
|
+
PARALLEL_SEARCH_URL,
|
|
7
|
+
ParallelApiError,
|
|
8
|
+
type ParallelSearchResult,
|
|
9
|
+
parseParallelErrorResponse,
|
|
10
|
+
parseParallelSearchPayload,
|
|
11
|
+
} from "../../parallel";
|
|
5
12
|
import { clampNumResults } from "../utils";
|
|
6
13
|
import type { SearchParams } from "./base";
|
|
7
14
|
import { SearchProvider } from "./base";
|
|
@@ -9,103 +16,6 @@ import { classifyProviderHttpError, toSearchSources, withHardTimeout } from "./u
|
|
|
9
16
|
|
|
10
17
|
const DEFAULT_NUM_RESULTS = 10;
|
|
11
18
|
const MAX_NUM_RESULTS = 40;
|
|
12
|
-
const PARALLEL_SEARCH_URL = "https://api.parallel.ai/v1beta/search";
|
|
13
|
-
const PARALLEL_BETA_HEADER = "search-extract-2025-10-10";
|
|
14
|
-
|
|
15
|
-
function isObject(value: unknown): value is object {
|
|
16
|
-
return typeof value === "object" && value !== null;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
function getOwnValue(value: object, key: string): unknown {
|
|
20
|
-
return Object.getOwnPropertyDescriptor(value, key)?.value;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
function getString(value: object, key: string): string | undefined {
|
|
24
|
-
const field = getOwnValue(value, key);
|
|
25
|
-
return typeof field === "string" ? field : undefined;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
function getObjectArray(value: object, key: string): object[] {
|
|
29
|
-
const field = getOwnValue(value, key);
|
|
30
|
-
return Array.isArray(field) ? field.filter(isObject) : [];
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
function getStringArray(value: object, key: string): string[] {
|
|
34
|
-
const field = getOwnValue(value, key);
|
|
35
|
-
return Array.isArray(field) ? field.filter((item): item is string => typeof item === "string") : [];
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
function extractParallelErrorMessage(payload: unknown): string | null {
|
|
39
|
-
if (!isObject(payload)) return null;
|
|
40
|
-
|
|
41
|
-
const directMessage = getString(payload, "message") ?? getString(payload, "detail") ?? getString(payload, "error");
|
|
42
|
-
if (directMessage && directMessage.trim().length > 0) {
|
|
43
|
-
return directMessage.trim();
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
const errorObject = getOwnValue(payload, "error");
|
|
47
|
-
if (isObject(errorObject)) {
|
|
48
|
-
const nestedMessage = getString(errorObject, "message") ?? getString(errorObject, "detail");
|
|
49
|
-
if (nestedMessage && nestedMessage.trim().length > 0) {
|
|
50
|
-
return nestedMessage.trim();
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
return null;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
function createParallelApiError(statusCode: number, detail?: string): ParallelApiError {
|
|
58
|
-
return new ParallelApiError(
|
|
59
|
-
detail ? `Parallel API error (${statusCode}): ${detail}` : `Parallel API error (${statusCode})`,
|
|
60
|
-
statusCode,
|
|
61
|
-
);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
function parseParallelErrorResponse(statusCode: number, responseText: string): ParallelApiError {
|
|
65
|
-
const trimmedResponseText = responseText.trim();
|
|
66
|
-
if (trimmedResponseText.length === 0) {
|
|
67
|
-
return createParallelApiError(statusCode);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
try {
|
|
71
|
-
const payload: unknown = JSON.parse(trimmedResponseText);
|
|
72
|
-
return createParallelApiError(statusCode, extractParallelErrorMessage(payload) ?? trimmedResponseText);
|
|
73
|
-
} catch {
|
|
74
|
-
return createParallelApiError(statusCode, trimmedResponseText);
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
function parseSearchPayload(payload: unknown): ParallelSearchResult {
|
|
79
|
-
if (!isObject(payload)) {
|
|
80
|
-
throw new ParallelApiError("Parallel search returned an invalid response payload.");
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
const requestId = getString(payload, "search_id") ?? "";
|
|
84
|
-
const rawResults = getObjectArray(payload, "results");
|
|
85
|
-
const sources: ParallelSearchSource[] = [];
|
|
86
|
-
|
|
87
|
-
for (const item of rawResults) {
|
|
88
|
-
const url = getString(item, "url");
|
|
89
|
-
if (!url) continue;
|
|
90
|
-
|
|
91
|
-
const excerpts = getStringArray(item, "excerpts");
|
|
92
|
-
const snippet = excerpts.length > 0 ? excerpts.join("\n\n") : undefined;
|
|
93
|
-
sources.push({
|
|
94
|
-
title: getString(item, "title") ?? url,
|
|
95
|
-
url,
|
|
96
|
-
snippet,
|
|
97
|
-
publishedDate: getString(item, "publish_date"),
|
|
98
|
-
excerpts,
|
|
99
|
-
});
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
return {
|
|
103
|
-
requestId,
|
|
104
|
-
sources,
|
|
105
|
-
warnings: [],
|
|
106
|
-
usage: [],
|
|
107
|
-
};
|
|
108
|
-
}
|
|
109
19
|
|
|
110
20
|
async function searchWithAuthStorage(
|
|
111
21
|
objective: string,
|
|
@@ -150,12 +60,13 @@ async function searchWithAuthStorage(
|
|
|
150
60
|
}),
|
|
151
61
|
signal: withHardTimeout(params.signal),
|
|
152
62
|
});
|
|
63
|
+
|
|
153
64
|
if (!response.ok) {
|
|
154
65
|
throw parseParallelErrorResponse(response.status, await response.text());
|
|
155
66
|
}
|
|
156
67
|
|
|
157
68
|
const payload: unknown = await response.json();
|
|
158
|
-
return
|
|
69
|
+
return parseParallelSearchPayload(payload, { parseMetadata: false });
|
|
159
70
|
},
|
|
160
71
|
{ signal: params.signal },
|
|
161
72
|
);
|
|
@@ -833,16 +833,28 @@ export class PerplexityProvider extends SearchProvider {
|
|
|
833
833
|
readonly id = "perplexity";
|
|
834
834
|
readonly label = "Perplexity";
|
|
835
835
|
|
|
836
|
+
/**
|
|
837
|
+
* Auto-chain admission. Requires a direct Perplexity credential
|
|
838
|
+
* (`PERPLEXITY_COOKIES`, OAuth session, or `PERPLEXITY_API_KEY`).
|
|
839
|
+
*
|
|
840
|
+
* OpenRouter auth is intentionally NOT accepted here: silently using
|
|
841
|
+
* OpenRouter's `perplexity/sonar-pro` whenever any OpenRouter key is
|
|
842
|
+
* configured surprises users (and bills them) for a path they never
|
|
843
|
+
* asked for. The auto chain skips Perplexity in that case and falls
|
|
844
|
+
* through to the next configured provider. Users who DO want the
|
|
845
|
+
* OpenRouter-backed Perplexity path can still opt in by setting
|
|
846
|
+
* `webSearch: perplexity` explicitly — see {@link isExplicitlyAvailable}.
|
|
847
|
+
*/
|
|
836
848
|
isAvailable(authStorage: AuthStorage): boolean {
|
|
837
|
-
return (
|
|
838
|
-
!!$env.PERPLEXITY_COOKIES?.trim() || authStorage.hasAuth("perplexity") || authStorage.hasAuth("openrouter")
|
|
839
|
-
);
|
|
849
|
+
return !!$env.PERPLEXITY_COOKIES?.trim() || authStorage.hasAuth("perplexity");
|
|
840
850
|
}
|
|
841
851
|
|
|
842
852
|
/**
|
|
843
|
-
* Perplexity accepts anonymous browser-style ask requests,
|
|
844
|
-
*
|
|
845
|
-
*
|
|
853
|
+
* Perplexity accepts anonymous browser-style ask requests, and the
|
|
854
|
+
* OpenRouter-backed `perplexity/sonar-pro` path is opt-in through
|
|
855
|
+
* explicit selection. Keep auto-chain admission credential-gated so a
|
|
856
|
+
* configured provider keeps priority over the anonymous/OpenRouter
|
|
857
|
+
* fallbacks.
|
|
846
858
|
*/
|
|
847
859
|
isExplicitlyAvailable(_authStorage: AuthStorage): boolean {
|
|
848
860
|
return true;
|