The Exa and Perplexity providers hard-coded request parameters that deployments should control while defaults are still unsettled. Exa gains searchType, numResults, and highlightsPerResult; Perplexity gains maxTokens (it previously sent none) and an optional searchRecency. Each follows the deepseek provider's shape: a defaulted Config field, a DEFAULT_* constant, and a positive-integer status() check for numeric limits. The call-level maxResults still flows through WebSearchRequest and wins over the configured default, keeping the seam layering intact. Addresses tianyicui's "make everything configurable" review comment.
63 lines
2.3 KiB
TypeScript
63 lines
2.3 KiB
TypeScript
/**
|
|
* `@deepseek-ai/dsh-web-search-perplexity`: registers a Perplexity-backed
|
|
* `WebSearchProvider` with `ctx.web`. A function/namespace plugin (NOT a
|
|
* default-export service): it registers INTO the seam's provider registry, like
|
|
* `@deepseek-ai/dsh-llm-deepseek` registers an adapter into `ctx.llm`.
|
|
*
|
|
* @module @deepseek-ai/dsh-web-search-perplexity
|
|
*/
|
|
|
|
import type { Context } from 'cordis'
|
|
import z from 'schemastery'
|
|
import type {} from '@deepseek-ai/dsh-web'
|
|
import { PerplexitySearchProvider, PERPLEXITY_DEFAULT_BASE_URL, PERPLEXITY_DEFAULT_MAX_TOKENS, PERPLEXITY_DEFAULT_MODEL } from './provider.ts'
|
|
|
|
export {
|
|
PERPLEXITY_DEFAULT_BASE_URL,
|
|
PERPLEXITY_DEFAULT_MAX_TOKENS,
|
|
PERPLEXITY_DEFAULT_MODEL,
|
|
PERPLEXITY_PROVIDER_ID,
|
|
PerplexitySearchProvider,
|
|
mapPerplexityResponse,
|
|
mapPerplexityResult,
|
|
} from './provider.ts'
|
|
export type { PerplexityRecency, PerplexitySearchProviderOptions } from './provider.ts'
|
|
|
|
/** Cordis plugin name used by loader diagnostics. */
|
|
export const name = 'web-search-perplexity'
|
|
|
|
/** The web seam this provider registers into. */
|
|
export const inject = ['web']
|
|
|
|
export interface Config {
|
|
/** Perplexity API key. Falls back to `$PERPLEXITY_API_KEY`. Empty → unavailable. */
|
|
apiKey?: string
|
|
/** Endpoint base; `/chat/completions` is appended. Defaults to the public API. */
|
|
baseURL?: string
|
|
/** Search model name. Defaults to `sonar`. */
|
|
model?: string
|
|
/** Upper bound on generated answer tokens. Defaults to 1024. */
|
|
maxTokens?: number
|
|
/** Recency window sent as `search_recency_filter`. Omitted = no filter. */
|
|
searchRecency?: 'day' | 'week' | 'month' | 'year'
|
|
}
|
|
|
|
export const Config: z<Config> = z.object({
|
|
apiKey: z.string(),
|
|
baseURL: z.string(),
|
|
model: z.string(),
|
|
maxTokens: z.number().step(1).min(1),
|
|
searchRecency: z.union(['day', 'week', 'month', 'year'] as const),
|
|
})
|
|
|
|
/** Register the Perplexity search provider with `ctx.web`. */
|
|
export function apply(ctx: Context, config: Config): void {
|
|
ctx.web.registerSearchProvider(new PerplexitySearchProvider({
|
|
apiKey: config.apiKey ?? process.env.PERPLEXITY_API_KEY ?? '',
|
|
baseURL: config.baseURL ?? PERPLEXITY_DEFAULT_BASE_URL,
|
|
model: config.model ?? PERPLEXITY_DEFAULT_MODEL,
|
|
maxTokens: config.maxTokens ?? PERPLEXITY_DEFAULT_MAX_TOKENS,
|
|
...config.searchRecency !== undefined ? { searchRecency: config.searchRecency } : {},
|
|
}))
|
|
}
|