Klavis SDK 升级全流程解析:基于 Fern 的 openapi.json 驱动代码生成与 PyPI/NPM 发布管线
2026/9/17 23:20:53 网站建设 项目流程

Klavis SDK 升级全流程解析:基于 Fern 的 openapi.json 驱动代码生成与 PyPI/NPM 发布管线

【免费下载链接】klavisKlavis AI: MCP integration platforms that let AI agents use tools reliably at any scale项目地址: https://gitcode.com/GitHub_Trending/kl/klavis

Klavis 仓库的fern/目录是整个 SDK 体系的"单一事实来源":本文以 fern/README.md 中描述的 SDK 升级三步流程为主线,结合 fern/generators.yml、fern/overrides.yml 与 SDK 发布工作流 等仓库证据,讲清楚"如何从一份 OpenAPI 规范出发,自动生成并发布 Python 与 TypeScript 双语言 SDK"。读完本文,你将掌握 Klavis SDK 的完整升级链路:规范更新、PR 合并、GitHub Actions 手动触发发布,以及 Fern 生成器的关键配置项各自影响 SDK 的哪一部分。

一、SDK 升级的官方三步流程

fern/README.md 定义了 Klavis SDK 升级的标准操作,全文共三步:

  1. 更新 openapi.json 文件:将最新的 API 规范写入openapi.json
  2. 提交 PR 并合并:把变更合并到 main 分支;
  3. 去 GitHub Actions 手动触发发布:点击Publish Python SDKPublish TypeScript SDK工作流,填写新版本号,流水线会自动生成并发布新版本 SDK。

整个流程的核心思想是:API 规范(OpenAPI)先行,SDK 代码零手写。开发者只需要维护规范文件,Python SDK 与 TypeScript SDK 的接口定义、类型、客户端方法全部由 Fern 生成器从规范推导而来。下面逐步拆解每一步在仓库中的落地形式。

二、第一步:更新 API 规范文件

规范文件的位置与引用方式

fern/generators.yml声明了生成器的输入规范:

api: specs: - openapi: ../docs/api-reference/openapi.json overrides: overrides.yml origin: https://api.klavis.ai/openapi.json

(见 fern/generators.yml)

  • openapi: ../docs/api-reference/openapi.json:本地仓库中的规范文件,实际位于 docs/api-reference/openapi.json。该文件是一份 OpenAPI 3.1.0 规范,标题为 "Klavis AI",声明了 US 与 EU 两套生产 API 服务器;
  • overrides: overrides.yml:指定类型重命名与 SDK 方法命名覆盖规则,见 fern/overrides.yml;
  • origin:生产环境规范的远端地址,用于在线同步(下文工作流部分会用到)。

如何更新规范

仓库提供了一条半自动的同步路径。.github/workflows/sync-openapi.yml 定义了名为Sync OpenAPI Specs的手动触发工作流,其核心步骤为:

- name: Update API with Fern uses: fern-api/sync-openapi@v2 with: update_from_source: true token: ${{ secrets.OPENAPI_SYNC_TOKEN }} branch: 'update-api' auto_merge: false add_timestamp: true

该工作流会从origin地址拉取线上最新 API 规范,写入update-api分支并自动追加时间戳,且auto_merge: false——即不会自动合并,必须走人工审查。这正对应 README 三步流程中的第二步:规范更新以 PR 形式进入 main 分支,保证 API 变更经过评审后才进入 SDK 生成链路。

从源码结构看,规范文件本身覆盖了三类接口域,与 SDK 最终暴露的模块一一对应:MCP 服务(如/mcp-server/call-tool/mcp-server/list-tools)、OAuth 授权(如/oauth/slack/authorize等数十个服务的 authorize 端点)、以及各类型沙箱的initialize/dump端点。

三、第二步:提交 PR 并合并到 main 分支

README 明确要求规范变更通过 PR 合并至 main。从仓库的 CI 结构可以推断这一设计的意图:

  • 发布工作流(见下节)以main分支上的fern/目录和docs/api-reference/openapi.json为输入,PR 合并是"规范冻结"的动作;
  • sync-openapi.ymlauto_merge: false配置保证了任何规范变更(无论是人工编辑还是从远端同步)都必须经过一次代码评审;
  • fern/README.md 中的顺序设计(先合并规范、后触发发布)意味着发布时点与 main 分支上的规范版本严格一致,避免"规范与 SDK 版本错位"。

这一步没有任何代码逻辑,其价值在于把 OpenAPI 文件变成受版本控制、受评审约束的发布契约

四、第三步:GitHub Actions 手动触发 SDK 发布

README 中的第三步对应仓库里两个workflow_dispatch手动触发的工作流。

Publish Python SDK

.github/workflows/python-sdk-release.yml 的完整执行链路为:

name: Publish Python SDK on: workflow_dispatch: inputs: version: description: "The version of the Python SDK that you would like to release" required: true type: string

执行步骤依次是:

  1. 检出代码(actions/checkout@v4),要求contents: write权限以打 tag;
  2. 全局安装 Fern CLI:npm install -g fern-api
  3. 执行发布命令,注入FERN_TOKENPYPI_TOKEN两个 secret:
fern generate --group python-sdk --version ${{ inputs.version }} --log-level debug

(见 python-sdk-release.yml)

  1. 使用softprops/action-gh-release@v1创建 GitHub Release,tag 为python-v${{ inputs.version }},自动基于上次 tag 以来的 commit 生成 release notes。

命令中的--group python-sdk精确指向generators.yml中定义的python-sdk生成组,--version即 README 所说的"specify new version"。

Publish TypeScript SDK

.github/workflows/typescript-sdk-release.yml 与 Python 版几乎同构,差异仅在:

  • 执行fern generate --group ts-sdk --version ${{ inputs.version }}(见 typescript-sdk-release.yml);
  • 注入FERN_TOKENNPM_TOKEN
  • GitHub Release 的 tag 前缀为ts-v${{ inputs.version }}

两条工作流的命名(Publish Python SDK/Publish TypeScript SDK)正是 README 第三步在 GitHub Actions 界面上看到的按钮名称。

五、generators.yml 深度解析:SDK 长什么样由这里决定

全局生成设置(api.specs.settings)

fern/generators.ymlsettings段(见 fern/generators.yml)控制规范到 SDK 类型的全局翻译规则:

配置项取值作用
title-as-schema-nametrue用 schema 的 title 作为类型名,使生成的类名更贴近 API 语义
type-dates-as-stringstrue日期字段统一生成为字符串类型,避免跨语言日期库差异
object-query-parametersfalse查询参数不包装成对象
idiomatic-request-namesfalse请求体类型名保持规范原名
respect-nullable-schemasfalse不强制按规范的 nullable 标注生成可空类型
wrap-references-to-nullable-in-optionaltrue指向可空 schema 的引用包装为 Optional
coerce-optional-schemas-to-nullabletrue可选 schema 归一化为可空类型
inline-path-parametersfalse路径参数保持独立,不内联进方法签名结构
coerce-enums-to-literalstrue枚举转换为字面量联合类型

这些布尔开关共同决定了生成 SDK 中类型可空性、命名风格等"手感"层面的行为,升级规范时如果某次 API 变更引入了新的可空字段,这些设置会影响新字段在 SDK 中的呈现方式。

python-sdk 生成组

python-sdk: generators: - name: fernapi/fern-python-sdk version: 4.32.2 output: location: pypi package-name: klavis token: ${PYPI_TOKEN} config: client_class_name: Klavis pydantic_config: enum_type: python_enums metadata: package-description: Open Source MCP Integration for AI applications license: Apache-2.0 smart-casing: true

(见 fern/generators.yml)

关键事实:

  • 产物发布到 PyPI,包名klavis,与 docs/sdk/python.mdx 中pip install klavis的安装方式一致;
  • 客户端类名固定为Klavis,即文档示例里klavis_client = Klavis(api_key="...")的入口;
  • 枚举使用 Python 原生Enumenum_type: python_enums),因此from klavis.types import McpServerName中的McpServerName.YOUTUBE是标准枚举成员;
  • 发布凭据来自环境变量${PYPI_TOKEN},与发布工作流中注入的 secret 名称相互印证。

ts-sdk 生成组

ts-sdk: generators: - name: fernapi/fern-typescript-node-sdk version: 1.7.0 output: location: npm package-name: klavis token: ${NPM_TOKEN} config: namespaceExport: Klavis allowCustomFetcher: true skipResponseValidation: true includeApiReference: true noSerdeLayer: true extraDevDependencies: msw: 2.11.2

(见 fern/generators.yml)

  • 产物发布到 npm,包名同样为klavis,与 docs/sdk/typescript.mdx 及 README.md 中import { KlavisClient, McpServerName } from 'klavis'的用法对应;
  • namespaceExport: Klavis提供命名空间导出;noSerdeLayer: true关闭序列化层,skipResponseValidation: true跳过响应校验,allowCustomFetcher: true允许调用方注入自定义 fetch 实现;
  • msw(Mock Service Worker)作为额外 dev 依赖被写进产物,供生成代码的测试使用。

六、overrides.yml:让生成结果符合 SDK 命名约束

OpenAPI 规范中的原始命名(带连字符的 schema 名、大量同构端点)直接生成会得到不可用的 SDK 代码,fern/overrides.yml 共 636 行,通过x-fern-*注解做了三类修正:

1. FastAPI 变体类型改名

FastAPI 会为响应模型生成-Input/-Output两个 schema 变体,overrides 将它们统一改名为合法驼峰标识符:

components: schemas: # Fix duplicate type names from FastAPI -Input/-Output schema variants AirtableData-Input: x-fern-type-name: AirtableDataInput AirtableData-Output: x-fern-type-name: AirtableDataOutput

(见 fern/overrides.yml,同类映射覆盖 Slack、Notion、GitHub 等数十个服务的数据类型)

2. 枚举值大写化

McpServerName枚举的显示名(如 "GitHub"、"YouTube")被映射为大写枚举成员:

McpServerName: x-fern-enum: "GitHub": name: GITHUB "YouTube": name: YOUTUBE

(见 fern/overrides.yml)这解释了 SDK 文档中McpServerName.YOUTUBE这类全大写成员的由来。

3. 端点归组与方法重命名

overrides 的paths段(见 fern/overrides.yml)把 REST 端点整理成 SDK 的分组方法:

  • POST /mcp-server/call-toolmcp_server.call_tools
  • POST /mcp-server/list-toolsmcp_server.list_tools
  • GET /mcp-server/tools/{serverName}mcp_server.get_tools
  • 每个/oauth/{service}/authorize端点归入oauth组并重命名为authorize_{service}(如authorize_gmailauthorize_slack);
  • 各沙箱的{service}/{sandbox_id}/initializedump端点分别重命名为initialize_{service}_sandbox/dump_{service}_sandbox,文件中的注释写明 "all 35 sandbox types need unique method names"——即靠重命名解决 35 种沙箱端点生成的方法名冲突问题。

从源码结构看,正是这些x-fern-sdk-group-name/x-fern-sdk-method-name注解,使得generators.yml生成的 SDK 呈现出klavis_client.mcp_server.call_tools(...)klavis_client.oauth.authorize_gmail(...)这类层级清晰的调用结构,与 docs/api-reference/sandbox 等 API 参考文档的分组保持一致。

七、发布后的验证路径

一次成功升级后,可以在仓库内通过以下路径验证 SDK 与规范的对应关系:

  • Python 安装与调用示例:docs/sdk/python.mdx(pip install klavis,含 OpenAI function calling 的完整示例);
  • TypeScript 安装与调用示例:docs/sdk/typescript.mdx;
  • 规范原文:docs/api-reference/openapi.json;
  • Fern 全局配置:fern/fern.config.json(组织名klavis、版本3.5.0)。

八、小结:一次完整升级的操作清单

把 README 的三步落到具体动作:

  1. 在 GitHub Actions 手动运行Sync OpenAPI Specs(或在本地编辑 docs/api-reference/openapi.json 并同步 fern/overrides.yml 中的命名修正),确认 diff 无误;
  2. 将变更以 PR 形式合并到 main 分支;
  3. 分别手动触发Publish Python SDKPublish TypeScript SDK,在version输入框填入目标版本号;流水线会自动执行fern generate --group python-sdk|ts-sdk,把新版本推送到 PyPI / npm,并创建python-v{version}/ts-v{version}的 GitHub Release。

需要说明的前提:触发发布工作流依赖仓库维护者配置的FERN_TOKENPYPI_TOKENNPM_TOKENOPENAPI_SYNC_TOKEN等 secrets,该操作属于仓库维护者权限;对于普通贡献者而言,可验证与可参与的环节集中在规范文件的 PR 修改与 overrides 规则的补充上。

【免费下载链接】klavisKlavis AI: MCP integration platforms that let AI agents use tools reliably at any scale项目地址: https://gitcode.com/GitHub_Trending/kl/klavis

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询