Authoring Custom Plugins
August 17, 2026 ยท View on GitHub
In Deepsiper Enthea, everything is a Cordis plugin. Capability seams, tools, evaluation metrics, and LLM providers are instantiated as composable plugins.
Plugin Structure
A typical plugin exports a name, dependency injections (inject), configuration schema (Config), and an apply activation function:
import { Context, Schema } from '@deepseek-ai/cordis'
export interface MyPluginConfig {
threshold?: number
enabled?: boolean
}
export const Config: Schema<MyPluginConfig> = Schema.object({
threshold: Schema.number().default(0.8).description('Evaluation pass threshold'),
enabled: Schema.boolean().default(true).description('Enable plugin execution'),
})
export const name = 'my-custom-eval'
export const inject = ['tools', 'session']
export function apply(ctx: Context, config: MyPluginConfig) {
// Register effects, lifecycle listeners, or tools
ctx.on('ready', () => {
ctx.logger('my-plugin').info('Custom eval plugin active with threshold %d', config.threshold)
})
// Register a custom evaluation tool
ctx.tools?.register({
name: 'custom_eval',
description: 'Executes benchmark validation on target candidate',
parameters: {
type: 'object',
properties: {
candidateId: { type: 'string' },
},
required: ['candidateId'],
},
async execute(args) {
return { score: 0.95, passed: true }
},
})
}
Lifecycle & Disposal
Cordis plugins automatically dispose registered resources when their parent fiber is unloaded. Always register listeners and timers via ctx.on and ctx.effect.