index.ts 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. /**
  2. * `@deepseek-ai/dsh-web-search-exa`: registers an Exa-backed `WebSearchProvider`
  3. * with `ctx.web`. A function/namespace plugin (NOT a default-export service):
  4. * a search provider does not own the `ctx.web` key — it registers INTO the
  5. * seam's provider registry, exactly as `@deepseek-ai/dsh-llm-deepseek`
  6. * registers an adapter into `ctx.llm`. The key is owned by `@deepseek-ai/dsh-web`.
  7. *
  8. * @module @deepseek-ai/dsh-web-search-exa
  9. */
  10. import type { Context } from 'cordis'
  11. import z from 'schemastery'
  12. import type {} from '@deepseek-ai/dsh-web'
  13. import {
  14. ExaSearchProvider,
  15. EXA_DEFAULT_BASE_URL,
  16. EXA_DEFAULT_HIGHLIGHTS_PER_RESULT,
  17. EXA_DEFAULT_SEARCH_TYPE,
  18. } from './provider.ts'
  19. export {
  20. EXA_DEFAULT_BASE_URL,
  21. EXA_DEFAULT_HIGHLIGHTS_PER_RESULT,
  22. EXA_DEFAULT_SEARCH_TYPE,
  23. EXA_PROVIDER_ID,
  24. ExaSearchProvider,
  25. } from './provider.ts'
  26. export type { ExaSearchProviderOptions } from './provider.ts'
  27. /** Cordis plugin name used by loader diagnostics. */
  28. export const name = 'web-search-exa'
  29. /** The web seam this provider registers into. */
  30. export const inject = ['web']
  31. /** Plugin config (all optional — `apply` fills env-var and constant defaults). */
  32. export interface Config {
  33. /** Exa API key. Falls back to `$EXA_API_KEY`. Empty → provider unavailable. */
  34. apiKey?: string
  35. /** Endpoint base; `/search` is appended. Defaults to the public API. */
  36. baseURL?: string
  37. /** Retrieval mode sent as Exa's `type`. Defaults to `auto`. */
  38. searchType?: 'auto' | 'keyword' | 'neural'
  39. /** Default result count when a request carries no `maxResults`. Omitted = none. */
  40. numResults?: number
  41. /** Highlight sentences requested per result. Defaults to 1. */
  42. highlightsPerResult?: number
  43. }
  44. export const Config: z<Config> = z.object({
  45. apiKey: z.string(),
  46. baseURL: z.string(),
  47. searchType: z.union(['auto', 'keyword', 'neural'] as const),
  48. numResults: z.number().step(1).min(1),
  49. highlightsPerResult: z.number().step(1).min(1),
  50. })
  51. /** Register the Exa search provider with `ctx.web`. */
  52. export function apply(ctx: Context, config: Config): void {
  53. ctx.web.registerSearchProvider(new ExaSearchProvider({
  54. apiKey: config.apiKey ?? process.env.EXA_API_KEY ?? '',
  55. baseURL: config.baseURL ?? EXA_DEFAULT_BASE_URL,
  56. searchType: config.searchType ?? EXA_DEFAULT_SEARCH_TYPE,
  57. highlightsPerResult: config.highlightsPerResult ?? EXA_DEFAULT_HIGHLIGHTS_PER_RESULT,
  58. ...config.numResults !== undefined ? { numResults: config.numResults } : {},
  59. }))
  60. }