首页
/ Context7 TypeScript SDK 版本演进解析:从 0.1.0 到 0.3.1 的 API 简化与错误处理加固

Context7 TypeScript SDK 版本演进解析:从 0.1.0 到 0.3.1 的 API 简化与错误处理加固

2026-09-04 23:54:55作者:舒璇辛Bertina

@upstash/context7-sdk 是 Context7 平台面向 TypeScript 的官方 SDK,用于在 AI Agent、RAG 管线中检索实时、带版本号的开源库文档。本文基于当前仓库中 packages/sdk/CHANGELOG.md 的完整版本记录,逐版本解读每次发布引入的 API 变化——包括 0.2.0 的破坏性 API 简化、0.3.0 默认响应类型从 txt 切换到 json、0.3.1 的非 JSON 错误体加固——并结合 入口实现HTTP 客户端 与对应测试用例,说明每个变更在源码中的落点与迁移注意点。读完后你可以明确:当前版本(0.3.1)的完整 API 面、各版本之间的不兼容边界,以及错误路径的行为契约。

版本演进总览

packages/sdk/CHANGELOG.md 记录了 4 个发布版本,与 packages/sdk/package.json"version": "0.3.1" 一致。总览如下:

版本 变更级别 核心变更
0.1.0 Minor(首次发布) 提供 HTTP/REST 客户端、searchLibrary()getDocs()、环境变量 API Key 支持
0.2.0 Minor(破坏性 API 简化) getDocs() 更名为 getContext(query, libraryId, options)searchLibrary() 改为双参数;响应类型统一为 Library / Documentation;移除分页、mode、topic、limit 等选项
0.3.0 Minor searchLibrarygetContext 的默认响应类型从 "txt" 改为 "json";AI SDK 工具显式使用 type: "txt" 获取 LLM 友好的纯文本
0.3.1 Patch 服务器返回非 JSON 错误体时不再抛出裸 SyntaxError,统一包装为带类型的 Context7Error

需要注意:packages/sdk/README.mddocs/sdks/ts/getting-started.mdx 均明确标注该 SDK 处于 Work in Progress 状态,“API 仍在活跃开发中,未来版本可能引入破坏性变更”。因此 0.1.0 到 0.3.0 虽然语义上是 Minor/Patch 级发布,0.2.0 与 0.3.0 实际上都改变了默认行为或方法签名,跨版本升级时必须对照下文逐节确认。

0.1.0:初始发布奠定 HTTP/REST 客户端基线

CHANGELOG 对 0.1.0(提交 5e11d35)的描述是“Context7 TypeScript SDK 首次发布”,包含三项能力:

  • HTTP/REST 客户端(对接 Context7 API)
  • searchLibrary() —— 在 Context7 数据库内搜索库
  • getDocs() —— 带过滤选项地拉取文档
  • API Key 的环境变量配置支持

这四项在源码中均可一一对应。当前 packages/sdk/src/client.ts 中的 Context7 类在构造时完成三件事:

  1. config.apiKeyprocess.env.CONTEXT7_API_KEY 的顺序解析 API Key,两者都缺失时抛出 Context7Error(“API key is required...”),这正是 0.1.0 承诺的“环境变量支持”的落地;
  2. 对 Key 做前缀校验——非 ctx7sk 前缀会打印 API key should start with 'ctx7sk' 警告(源码中 API_KEY_PREFIX = "ctx7sk");
  3. 内部实例化 HttpClient,固定 baseUrlhttps://context7.com/api,并预置 Bearer 认证头、5 次重试与 Math.exp(retryCount) * 50 毫秒的指数退避、以及 cache: "no-store" 缓存策略。

HttpClientpackages/sdk/src/http/index.ts)是 SDK 唯一的网络出口,封装了 fetch 调用、重试循环、响应解析与错误归一化。0.1.0 的 getDocs() 在 0.2.0 中已被移除,其“过滤选项”(分页、mode、topic、limit)也随之取消——下文 0.2.0 小节会详细说明这一取舍。

0.2.0:破坏性的 API 简化——从 getDocs 到 getContext

0.2.0(提交 b3cd38a)是一次以“简化”为目标的接口重构,CHANGELOG 列出的每一条变更都可以在当前源码中找到对应形态:

方法签名重构

  • getDocs() 被替换为 getContext(query, libraryId, options)。新签名要求传入 query 参数(用户的问题或任务),用于服务端做相关性排序检索,而不再是无差别拉取。对照 packages/sdk/src/commands/get-context/index.ts:命令构造时把 querylibraryIdtype 组装成 GET 查询参数,请求 v2/context 端点。
  • searchLibrary(query, libraryName) 改为双参数。此前只需库名,现在必须同时提供“相关性 query”与“库名”。packages/sdk/src/commands/search-library/index.ts 在构造函数中显式校验:querylibraryName 为空即抛出 Context7Error("query and libraryName are required"),请求命中 v2/libs/search 端点。

响应类型统一

CHANGELOG 说明响应类型被替换为 LibraryDocumentation 两个模型,取代旧版 SearchResultCodeDocsResponseInfoDocsResponse 等分散类型。当前定义集中在 packages/sdk/src/commands/types.ts

export interface Library {
  id: string;            // Context7 库 ID,如 "/react/react"
  name: string;          // 显示名
  description: string;   // 库描述
  totalSnippets: number; // 可用文档片段数
  trustScore: number;    // 来源可信度分数(0-10)
  benchmarkScore: number; // 质量指标分数(0-100)
  versions?: string[];   // 可用版本/标签
}

export interface Documentation {
  title: string;   // 文档片段标题
  content: string; // 文档内容(可含 Markdown 代码块)
  source: string;  // 来源 URL 或标识
}

packages/sdk/src/utils/format.ts 的格式化函数可以看清“统一”的具体做法:服务端返回的 codeSnippets(含 codeTitlecodeDescriptioncodeListcodeId 等原始字段)被 formatCodeSnippet 拼装成 { title, content, source }——代码块以 ```language 围栏重新封装进 content,描述前置;infoSnippetsformatInfoSnippet 映射为同构形状(面包屑作为 title,缺失时回退为 "Documentation")。两类原始响应在 GetContextCommand.exec 中被合并为单一 Documentation[] 返回([...codeDocs, ...infoDocs]),调用方不再需要区分“代码文档”与“信息文档”两种类型。

移除分页与过滤选项

CHANGELOG 明确写道:“Remove pagination, mode, topic, and limit options from context retrieval”,并且 GetContextOptions 被简化到只剩 type: "json" | "txt" 一个字段。这一点在 types.ts 中得到印证——GetContextOptionsSearchLibraryOptions 均只有一个可选的 type 属性。检索的分页/模式/数量控制被上收到服务端默认策略,SDK 调用方只关心“问题 + 库 + 返回格式”。

迁移提示:如果你的代码仍在使用 0.1.0 的 getDocs(libraryId, { mode, topic, limit, page }) 形态,需要改写为 getContext(query, libraryId, { type }),并把原来依赖分页遍历的逻辑改为“一次相关性检索”。

0.3.0:默认响应类型从 txt 切换到 json

0.3.0(提交 9412e62)的变更一句话概括:“Change SDK default response type from 'txt' to 'json' for both searchLibrary and getContext methods. AI SDK tools now explicitly use type: 'txt' for LLM-friendly text responses.”

默认值变更的源码落点

两个命令各自定义了 DEFAULT_TYPE = "json"

配合 client.ts 中的三重载签名,TypeScript 层面能按 type 字面量推导出精确返回类型:

// type: "json" → Library[]
async searchLibrary(query: string, libraryName: string,
  options: SearchLibraryOptions & { type: "json" }): Promise<Library[]>;
// type: "txt" → string
async searchLibrary(query: string, libraryName: string,
  options: SearchLibraryOptions & { type: "txt" }): Promise<string>;
// 不传 options → 默认 JSON
async searchLibrary(query: string, libraryName: string,
  options?: SearchLibraryOptions): Promise<Library[]>;

getContext 的三重载结构与之完全对称(Documentation[] / string / 默认 Documentation[]),见 client.ts。这意味着 0.3.0 之后,不传 options 的调用方拿到的是结构化数组而不是字符串——对以 0.2.x 时代 txt 为默认写的代码是一次隐性破坏:原本 const text = await client.getContext(...) 得到的字符串,升级后变成 Documentation[],需要显式传 { type: "txt" } 或改为遍历数组。仓库中的测试(如 packages/sdk/src/client.test.tspackages/sdk/src/commands/get-context/index.test.ts)均以 { type: "txt" } 显式断言文本路径。

设计动机:JSON 给代码,TXT 给 LLM

从仓库结构看,这一拆分的另一侧消费者是 AI SDK 工具包。docs/agentic-tools/ai-sdk/agents/tools 下的 resolve-library-id.mdxquery-docs.mdx 文档描述了 @upstash/context7-tools-ai-sdk 提供的两个工具,其实现位于 packages/tools-ai-sdk/src/tools:这些 Agent 工具内部调用 SDK 时显式传 type: "txt",因为纯文本格式(库搜索结果由 formatLibrariesAsText 渲染为 “Title / library ID / Description / Trust Score…” 的分节文本)可以直接塞进 LLM prompt,无需模型自己解析 JSON。而程序化场景(RAG 管线、需要逐片段处理或统计 token 的调用方)则受益于默认 json 结构化的 Documentation[]。简言之,0.3.0 把“默认格式”的决策权交还给了调用场景,而不是替所有场景默认选文本。

txt 路径的附赠能力:分页响应头

值得留意的是,即便 0.2.0 移除了客户端分页参数,txt 路径仍保留分页元数据。HttpClient.request 对非 JSON 响应会解析 x-context7-pagex-context7-limitx-context7-total-pagesx-context7-has-nextx-context7-has-prevx-context7-total-tokens 六个响应头,聚合成 TxtResponseHeaders 对象随结果一并返回(类型定义)。从源码结构看,这是为 txt 分页游标语义预留的通道——服务端仍在按页返回文本,SDK 只是把“跳页”的能力留给了响应头而非请求参数。

0.3.1:错误路径加固——非 JSON 错误体不再裸抛 SyntaxError

0.3.1(提交 f327589)是当前版本,修复了一个生产环境常见的崩溃源。CHANGELOG 原文:“Avoid throwing a raw SyntaxError when the server returns a non-JSON error body. HttpClient.request() now wraps the error-path res.json() in a .catch, so non-JSON responses (HTML 502s, plain-text 429s, Cloudflare challenge pages) fall back to res.statusText and always surface as a typed Context7Error.”

问题背景

HTTP 客户端在 !res.ok 时习惯性地执行 await res.json() 提取错误信息。但当中间层(负载均衡、CDN 边缘节点、限流网关)返回 HTML 502 页面、纯文本 429 或 Cloudflare 质询页时,res.json() 解析失败会抛出 JavaScript 原生 SyntaxError: Unexpected token <...——这不是业务错误,调用方的 catch (e) { if (e instanceof Context7Error) ... } 分支无法捕获语义,日志里也丢失了真实 HTTP 状态信息。

修复实现

修复位于 packages/sdk/src/http/index.ts 的错误分支:

if (!res.ok) {
  const errorBody = (await res.json().catch(() => ({}))) as {
    error?: string;
    message?: string;
  };
  throw new Context7Error(errorBody.error || errorBody.message || res.statusText);
}

三级回退链非常明确:

  1. JSON 错误体的 error 字段;
  2. JSON 错误体的 message 字段;
  3. 都不是(含非 JSON 响应导致 .catch(() => ({})) 兜底)时,回退到 res.statusText(如 "Bad Gateway"、"Service Unavailable")。

任何情况下抛出的都是 Context7Error(继承 Errorname = "Context7Error"),与 docs/sdks/ts/getting-started.mdx 中“Error Handling”一节承诺的 error instanceof Context7Error 判定契约完全一致。

测试佐证

packages/sdk/src/http/index.test.ts 用 vitest + 全局 mock fetch 覆盖了三条回退路径:

  • 429 JSON 错误体:断言 Context7Error("rate limit exceeded")error 字段路径);
  • 400 仅含 message 字段:断言回退到 message
  • 502 HTML 错误体:断言抛出的Context7Error 且不是 SyntaxErrormessage"Bad Gateway"——这条用例正是 0.3.1 修复行为的直接回归测试;
  • 503 空错误体:断言回退到 statusText("Service Unavailable")。

对使用者的实际影响是:在 Agent 或长驻服务中集成 SDK 时,try/catch Context7Error 一个分支就能兜住所有 API 侧故障,无需再防御性处理 SyntaxError

当前版本(0.3.1)API 速查与迁移清单

综合四个版本的变更,0.3.1 的对外 API 面收敛为:一个 Context7 客户端类 + 两个方法 + 一组导出类型 + 一个错误类。

import { Context7, Context7Error } from "@upstash/context7-sdk";

const client = new Context7({ apiKey: "ctx7sk-..." });
// 或依赖环境变量:CONTEXT7_API_KEY="ctx7sk-..." 后 new Context7()

// 1) 搜索库(默认 JSON → Library[])
const libs = await client.searchLibrary("I need to build a UI with components", "react");
console.log(libs[0].id); // 例如 "/facebook/react"

// 2) 获取文档上下文(默认 JSON → Documentation[])
const docs = await client.getContext("How do I use hooks?", "/facebook/react");
docs.forEach((d) => console.log(d.title, d.content, d.source));

// 3) LLM prompt 场景用纯文本
const context = await client.getContext("How do I use hooks?", "/facebook/react", {
  type: "txt",
});

关键参数与默认值(依据 types.tsclient.ts):

说明 默认值
Context7Config.apiKey API Key;缺失时读取 CONTEXT7_API_KEY,再缺失则抛 Context7Error 无(必填其一)
searchLibrary(query, libraryName, options?) 双参数均为必填,空值抛错;命中 v2/libs/search type: "json"
getContext(query, libraryId, options?) query 用于相关性排序,libraryId 形如 /facebook/react;命中 v2/context type: "json"
options.type "json" 返回结构化数组 / "txt" 返回可直接入 prompt 的文本 "json"
内部重试 5 次重试,退避 exp(n) * 50 ms,cache: "no-store"(构造函数内固定,不对外暴露)

跨版本迁移检查单:

  • 从 0.1.x 升级getDocs() 已不存在,替换为 getContext(query, libraryId)searchLibrary 需补第二个参数 query;删除所有 mode / topic / limit / 分页传参。
  • 从 0.2.x 升级:核对未传 type 的调用——0.3.0 起默认返回结构化数组,需要文本的调用点显式补 { type: "txt" }
  • 所有版本:统一用 error instanceof Context7Error 捕获 API 侧错误,0.3.1 之后该判定覆盖非 JSON 错误体场景。

小结

packages/sdk/CHANGELOG.md 这条从 0.1.0 到 0.3.1 的演进线,呈现了一个典型的 SDK 成熟过程:0.1.0 建立“Key 管理 + 搜索 + 取文档”三件套;0.2.0 用一次破坏性简化把分散的响应类型收敛为 Library / Documentation,并用相关性 query 取代手工分页/过滤;0.3.0 把默认响应格式从 LLM 文本切回程序友好的 JSON,把 txt 显式让渡给 AI SDK 工具类消费者(如 packages/tools-ai-sdk/src/tools 中的实现);0.3.1 则补齐了网络错误路径的类型化契约。当前代码、类型定义与 http 层测试 三者一致地印证了 CHANGELOG 的每一项描述,读者若基于该 SDK 构建文档驱动的 Agent,建议锁定 0.3.1 的上述行为契约,并留意 README 中“API 仍可能破坏性变更”的 WIP 声明。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.12 K
2.72 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
527
590
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
904
1.82 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
854
1.34 K
docsdocs
暂无描述
Markdown
889
5.78 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.52 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.33 K
1.45 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
981
502
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
540
384