DeepSeek Harness101 开发工具 返回首页 官方教程 ↗

类型与运行时校验

让插件配置成为明确契约。

用同名 Config 类型和 Schemastery schema 接收配置,在加载时校验并填充默认值。

前置条件沿用前两篇教程的 scratch-plugin。本页会把 greet 的行为改成可配置。
scratch-plugin/src/my-plugin.ts
import type { Context } from '@deepseek-ai/cordis'
import Schema from '@deepseek-ai/schemastery'

export const name = 'my-plugin'

export interface Config {
  greeting: string
  maxRetries: number
  verbose?: boolean
}

export const Config: Schema<Config> = Schema.object({
  greeting: Schema.string().default('Hello'),
  maxRetries: Schema.number().default(3),
  verbose: Schema.boolean().default(false),
})

export function apply(ctx: Context, config: Config) {
  console.log(config.greeting)
}

配置在加载时完成四件事

TypeScript 类型服务开发期,Schemastery schema 负责运行时。两者同名,但职责不同。

cordis.yml

读取用户值

config 节点提供当前部署的选择。

Config schema

校验并补默认值

字段规则在插件加载期间执行。

apply(ctx, config)

传入类型安全对象

apply 读取用户值或 schema 默认值。

plugin instance

按配置运行

实现无需重新解析原始 YAML。

在原有插件行增加 config

保留“第一个插件”教程中已经验证的绝对路径,只增加 config 节点。这样 greeting 覆盖默认值,未写入的 verbose 仍使用 false。

scratch-plugin/cordis.yml
- insert:
    - id: hello
      name: '/absolute/path/to/deepseek-harness/scratch-plugin/src/my-plugin.ts'
      config:
        greeting: 'Hi there'
        maxRetries: 5
来源差异

官方配置篇片段使用 ./src/my-plugin.ts,但同一提交的第一篇教程明确说明 patch 不改变模块解析所用的 profile 目录,并要求绝对路径。本站保持绝对路径,避免教程链在此中断。

把无效配置挡在插件加载阶段

required、default 和 union 都属于 schema。无效值应让插件以明确错误停止加载,而不是带着错误状态进入执行路径。

TypeScript
export interface Config {
  apiKey: string
  timeout: number
  mode: 'fast' | 'accurate'
}

export const Config = Schema.object({
  apiKey: Schema.string().required(),
  timeout: Schema.number().default(30000),
  mode: Schema.union(['fast', 'accurate']).default('fast'),
})

不要导出普通对象作为 Config。Cordis 需要它实现 Standard Schema 接口。

一个简单判断标准

如果两个部署可能需要不同值,它就应该是配置字段,而不是代码常量。

不要硬编码const TIMEOUT = 30000
交给配置timeoutMs: number

配置修改会热替换插件实例

框架先卸载旧实例,再加载新实例。通过 ctx 注册的 effect 会自动清理,所以旧注册不会残留。

修改 config卸载旧实例清理注册加载新实例

下一步,打包并安装插件