{"_id":"@buddhilive/dsh-web-search-exa","name":"@buddhilive/dsh-web-search-exa","dist-tags":{"alpha":"0.1.2-alpha.3","latest":"0.1.2-alpha.3"},"versions":{"0.1.2-alpha.3":{"name":"@buddhilive/dsh-web-search-exa","description":"Exa-backed search provider for the DeepSeek Harness web capability seam (ctx.web)","version":"0.1.2-alpha.3","publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/Buddhilive/buddhi-ai-harness.git","directory":"packages/web/web-search-exa"},"type":"module","main":"lib/index.js","types":"lib/types/index.d.ts","exports":{".":{"types":"./lib/types/index.d.ts","default":"./lib/index.js"},"./invariant":{"types":"./lib/types/invariant.d.ts","default":"./lib/invariant.js"},"./src/*":"./src/*","./package.json":"./package.json"},"license":"MIT","peerDependencies":{"@buddhilive/dsh-launch-environment":"^0.1.2-alpha.3","@buddhilive/dsh-web":"^0.1.2-alpha.3","@buddhilive/dsh-invariants":"^0.1.2-alpha.3","@deepseek-ai/cordis":"^4.0.2"},"dependencies":{"@deepseek-ai/schemastery":"^3.18.2"},"devDependencies":{"@buddhilive/dsh-launch-environment":"^0.1.2-alpha.3","@buddhilive/dsh-web":"^0.1.2-alpha.3","@buddhilive/dsh-invariants":"^0.1.2-alpha.3","@deepseek-ai/cordis":"^4.0.2"},"_id":"@buddhilive/dsh-web-search-exa@0.1.2-alpha.3","bugs":{"url":"https://github.com/Buddhilive/buddhi-ai-harness/issues"},"homepage":"https://github.com/Buddhilive/buddhi-ai-harness#readme","_integrity":"sha512-YVoSxevsOLF6McHwR9ibq1fxkJinUo/20OXY7NVZm5yvBXyfZM3QlbNk1VlKexRd35xGPXO3Bt0dyq+48O6J1A==","_resolved":"C:\\DevDojo\\Buddhi\\buddhi-ai-harness\\dist\\npm\\buddhilive-dsh-web-search-exa-0.1.2-alpha.3.tgz","_from":"file:C:/DevDojo/Buddhi/buddhi-ai-harness/dist/npm/buddhilive-dsh-web-search-exa-0.1.2-alpha.3.tgz","_nodeVersion":"24.13.0","_npmVersion":"11.6.2","dist":{"integrity":"sha512-YVoSxevsOLF6McHwR9ibq1fxkJinUo/20OXY7NVZm5yvBXyfZM3QlbNk1VlKexRd35xGPXO3Bt0dyq+48O6J1A==","shasum":"59448f155424e77e4c7855ea172a13d7e93e10f4","tarball":"https://registry.npmjs.org/@buddhilive/dsh-web-search-exa/-/dsh-web-search-exa-0.1.2-alpha.3.tgz","fileCount":11,"unpackedSize":32662,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDpQDKkLvPGmkfVN9iX2jGIUO3CO1R8gA4Au1kJAghNEgIgeNgbif1EF9o2XwUGH5GbSdwu3kdUTTv10OIDTrOhf+w="}]},"_npmUser":{"name":"buddhilive","email":"visitbudkavin@gmail.com"},"directories":{},"maintainers":[{"name":"buddhilive","email":"visitbudkavin@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/dsh-web-search-exa_0.1.2-alpha.3_1788166804190_0.6670404752364223"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-31T09:00:03.872Z","0.1.2-alpha.3":"2026-08-31T09:00:04.305Z","modified":"2026-08-31T09:00:04.729Z"},"maintainers":[{"name":"buddhilive","email":"visitbudkavin@gmail.com"}],"description":"Exa-backed search provider for the DeepSeek Harness web capability seam (ctx.web)","homepage":"https://github.com/Buddhilive/buddhi-ai-harness#readme","repository":{"type":"git","url":"git+https://github.com/Buddhilive/buddhi-ai-harness.git","directory":"packages/web/web-search-exa"},"bugs":{"url":"https://github.com/Buddhilive/buddhi-ai-harness/issues"},"license":"MIT","readme":"---\ndescription: \"ctx.web 的 Exa 搜索提供方：部署方如何挂载厂商原生 web 搜索，获得可移植 snippet 与发布日期。\"\nkind: \"package-reference\"\n---\n\n# @buddhilive/dsh-web-search-exa\n\n[English](README.md) | 中文\n\n## 概述\n\n有了 `dsh-web-search-exa`，harness 可以通过 Exa 搜索 web，获得带可移植 snippet 与发布日期的厂商原生结果。当部署持有 Exa API 密钥、并希望使用 Exa 的关键词或神经搜索时选择它。Exa 不返回生成答案，因此结果不携带 `content`——只产出可引用的来源。没有非空白高亮的来源会被丢弃，因此一次调用返回的来源可能少于请求数量。面向模型的 `web_search` 工具位于 `dsh-tool-web`。\n\n## 目录\n\n- [使用本包](#use-this-package)\n- [理解实现](#understand-the-implementation)\n- [进一步探索](#further-exploration)\n- [模型体验](#model-experience)\n- [已知限制与延期工作](#known-limitations-and-deferred-work)\n- [开发备注](#dev-note)\n\n-----\n\n<a id=\"use-this-package\"></a>\n## 使用本包\n\n在已加载 web 服务的组合中挂载本提供方；它以 `exa` 搜索提供方身份注册，因此当它是唯一可用的搜索后端时，`ctx.web.search()` 会自动解析到它——也可以用 `searchProvider: exa` 固定。\n\n### 何时选择\n\n当部署持有 Exa API 密钥、并希望使用 Exa 的关键词或神经搜索、获得带每结果高亮 snippet 与发布日期时选择此后端。密钥为空或端点基址无法解析时，提供方不可用——每次搜索调用都会以结构化错误失败。\n\n### 最小配置\n\n加载 web 服务与本提供方；API 密钥回退到启动环境中的 `$EXA_API_KEY`，其余设置都有安全默认值。\n\n```yaml\n- name: '@buddhilive/dsh-web'\n- name: '@buddhilive/dsh-web-search-exa'\n  config:\n    apiKey: !!js process.env.EXA_API_KEY\n```\n\n| 字段 | 默认值 | 含义 |\n|---|---|---|\n| `apiKey` | `$EXA_API_KEY` | Exa API 密钥；为空或缺失时提供方不可用 |\n| `baseURL` | `https://api.exa.ai` | 端点基址；追加 `/search`。无法解析时提供方不可用 |\n| `searchType` | `auto` | 以 Exa `type` 发送的检索模式：`auto`、`keyword` 或 `neural` |\n| `numResults` | （未设置） | 请求不含 `maxResults` 时使用的默认结果数；必须是正整数 |\n| `highlightsPerResult` | `1` | 每个结果请求的 highlight 句子数（Exa `highlightsPerUrl`）；必须是正整数 |\n\n生成的[配置目录](../../../docs/config-catalog.zh.md#buddhilivedsh-web-search-exa)是每个受支持字段及其 JSDoc 的穷尽式真源。\n\n### 搜索返回什么\n\n每项 Exa 结果映射为 `WebSearchSource`：`url`、`title`、以首个非空白高亮作为 `snippet`、`publishedDate` 作为 `publishedAt`；没有高亮的来源缺少可移植的 snippet，会被丢弃。请求的 `maxResults` 优先于已配置的默认 `numResults`，并作为成本与延迟优化发送给 Exa——最终上限由服务强制执行：截断并标记。Exa 不返回生成答案，因此结果不携带 `content`。\n\n### 失败与恢复\n\n提供方失败——HTTP 错误、网络失败、响应体无法解析或结构不符——以 `WebError` `WEB_PROVIDER_ERROR` 呈现；中止请求以 `WEB_ABORTED` 呈现。HTTP 重定向会在访问 `Location` 指向的目标之前被拒绝，并以 `WEB_PROVIDER_ERROR` 呈现。调用方按 code 路由；面向模型的 `web_search` 工具会在自己的错误包装层内把失败呈现给模型。\n\n-----\n\n<a id=\"understand-the-implementation\"></a>\n## 理解实现\n\n<details>\n<summary>实现细节——点击展开</summary>\n\n本节解释提供方背后的设计决策；可观察行为已在[使用本包](#use-this-package)中完整说明。\n\n### 设计理念\n\n该提供方是 Exa API 之上的薄适配器，遵循两条刻意的规则：\n\n- **只取可移植的 snippet。** 来源只有在真实高亮存在时才获得 `snippet`；用其他字段捏造会让 seam 说谎，因此没有 snippet 的结果被整个丢弃。\n- **不虚构答案。** Exa 不返回生成答案，因此省略 `content`，而不是编造模型可能信任的提供方文本。\n\n### 源码地图\n\n| 文件 | 职责 |\n|---|---|\n| [`src/index.ts`](src/index.ts) | 插件入口：配置 schema、环境变量回退、提供方注册 |\n| [`src/provider.ts`](src/provider.ts) | `ExaSearchProvider`：请求分发、中止分类、结果映射 |\n| [`src/types.ts`](src/types.ts) | Exa 协议类型：`ExaSearchResponse`、`ExaResult`、`ExaError` |\n| [`src/invariant.ts`](src/invariant.ts) | 不变式伴生插件（无运行时不变式；约定在服务处强制执行） |\n\n### 请求与映射流程\n\n`search()` 以 `redirect: 'error'` 把查询、检索模式、高亮请求与可选结果数 POST 到 `{baseURL}/search`，因此重定向会在不接触目标的情况下使请求失败。解析后的 `results[]` 逐项映射，没有 snippet 的条目被丢弃，服务在返回路径上应用最终的 `maxResults` 上限。中止——名为 `AbortError` 的 `DOMException`——变为 `WEB_ABORTED`；其余情况变为 `WEB_PROVIDER_ERROR`。\n\n</details>\n\n-----\n\n<a id=\"further-exploration\"></a>\n## 进一步探索\n\n当包级约定不够用时阅读以下页面。它们从共享词汇逐步进入服务、面向模型的工具与设计依据。\n\n- [web 子系统](../../../docs/subsystems/web.zh.md)——穷尽式的搜索请求／结果词汇与错误码。\n- [web 包映射](../README.zh.md)——六包家族与各角色。\n- [dsh-web](../web/README.zh.md)——本提供方注册进入的 web 服务。\n- [dsh-tool-web](../tool-web/README.zh.md)——渲染本提供方来源的面向模型 `web_search` 工具。\n- [生成配置目录](../../../docs/config-catalog.zh.md#buddhilivedsh-web-search-exa)——每个受支持配置字段及其源声明。\n- [web 能力 seam 决策](../../../.agents/notes/implemented/architecture/2026-06-24-web-capability-seam.zh.md)——搜索与抓取为何共用一项提供方选择服务。\n\n-----\n\n<a id=\"model-experience\"></a>\n## 模型体验\n\n间接地，通过 `dsh-tool-web`：该工具把本提供方经 `maxResults` 限制的 URL、标题、首条高亮与发布日期，或将确切的错误消息 `Exa search aborted`、`Exa search request failed: <error>` 和 `Exa returned an unprocessable response body: <error>` 保留在消费方的错误包装层内。\n\n#### KV Cache 影响\n\n不会直接导致 KV Cache 失效；请求前缀变更由上述消费方负责。\n\n## 已知限制与延期工作\n\n<a id=\"known-limitations-and-deferred-work\"></a>\n\n\n这些限制说明提供方在哪些情况下不合适。它们是当前包约束。\n\n- **没有非空白高亮的来源会被整个丢弃**——没有可映射的可移植 snippet，因此返回来源可能少于请求数量。\n- **只公开 `searchType`／`numResults`／`highlightsPerResult`**——Exa 的其他控制项（livecrawl、category、域名／日期过滤条件、全文内容）等待提供方无关的服务字段（见 [seam Agent Note](../../../.agents/notes/implemented/architecture/2026-06-24-web-capability-seam.zh.md)）。\n- **按错误形状分类中止**——只有名为 `AbortError` 的 `DOMException` 才映射为 `WEB_ABORTED`；携带自定义原因的中止（例如 `dsh-timeout` 的 `TimeoutReason`）呈现为 `WEB_PROVIDER_ERROR`。\n\n<a id=\"dev-note\"></a>\n### 开发备注\n\n<details>\n<summary>维护者的工作上下文——点击展开</summary>\n\n本开发备注是维护者的工作上下文：开放问题与尚未决定的探索方向。它明确不具权威性——已交付的行为、限制与既定理由以上文和相关 Agent Note 为准。\n\n#### 未来：更宽的 Exa 控制面\n\nExa 的 livecrawl、category、域名与日期过滤条件以及全文内容仍未公开。公开它们需要先有提供方无关的服务字段，让家族以一个协调一致的控制项、而非厂商专有参数的方式新增。\n\n</details>\n","readmeFilename":"README.zh.md","_rev":"1-5c1dc416e393e4252a97352aef8b9aab"}