Plugin Configuration
Build strictly-typed configuration schemas with default values, environment variable parsing, and hot updates.
In building resilient enterprise-grade agent systems, “No Hardcoded Tunable Parameters” is a fundamental architectural invariant of DeepSeek Harness. Network timeouts, concurrency thresholds, gateway endpoints, and authentication tokens should all be declaratively managed in configuration files.
DeepSeek Harness integrates @deepseek-ai/schemastery to provide a strongly-typed configuration algebra, supporting compile-time inference, runtime validation, and automated default value injection for cordis.yml.
This tutorial uses an “Inference Gateway & Rate Limiter Plugin” as a real-world case study to unpack configuration schemas and sensitive credential masking.
Core Paradigm: Dual Export & Standard Schema
In Cordis, configuration contracts are declared through a same-named dual export pattern: exporting both a TypeScript interface Config and a matching export const Config: Schema<Config> runtime validator:
import type { Context } from '@deepseek-ai/cordis';
import Schema from '@deepseek-ai/schemastery';
export const name = 'inference-gateway-plugin';
// 1. Compile-time static type interface (enables IDE auto-completion)
export interface Config {
endpoint: string;
maxConcurrency: number;
timeoutMs: number;
enableFallback?: boolean;
}
// 2. Runtime Schema validator (parses YAML, injects defaults, blocks invalid keys)
export const Config: Schema<Config> = Schema.object({
endpoint: Schema.string().required().description('Base endpoint URL for the model proxy gateway'),
maxConcurrency: Schema.number().default(5).min(1).max(50).description('Maximum allowable concurrent requests'),
timeoutMs: Schema.number().default(15000).description('Request timeout threshold in milliseconds'),
enableFallback: Schema.boolean().default(true).description('Automatically switch to fallback routes upon gateway failure')
});
// 3. apply function receives the sanitized config object with injected defaults
export function apply(ctx: Context, config: Config) {
console.log(`[Gateway] Connected to endpoint: ${config.endpoint} (Concurrency: ${config.maxConcurrency})`);
}
Crucial Architecture Rule: Never export a plain JavaScript literal object as
Config. The Cordis microkernel requires configuration definitions to implement the Standard Schema specification for static inference and runtime sandboxing.
Step 1: Supplying Configuration via cordis.yml
Inject parameters into your local plugin within cordis.yml:
- insert:
- id: gateway-instance
name: './custom-plugins/gateway'
config:
endpoint: 'https://api.deepseek.com/v1'
maxConcurrency: 10
timeoutMs: 20000
enableFallback: false
During startup, Harness reconciles YAML values against the schema, populating defaults for any omitted properties.
Step 2: Strict Validation and the "Fail Loudly" Principle
For mission-critical production plugins, combine Schemastery operators to embrace the Fail Loudly principle:
import type { Context } from '@deepseek-ai/cordis';
import Schema from '@deepseek-ai/schemastery';
export const name = 'secure-vault-plugin';
export interface Config {
masterApiKey: string;
environment: 'production' | 'staging' | 'development';
ipWhitelist: string[];
rateLimitPerMinute: number;
}
export const Config: Schema<Config> = Schema.object({
// required() enforces presence; .role('secret') masks values across logs & UI
masterApiKey: Schema.string().required().role('secret').description('Master authentication token'),
// union specifies strict enum constraints
environment: Schema.union(['production', 'staging', 'development']).default('development').description('Target execution tier'),
// array declares typed list validation
ipWhitelist: Schema.array(Schema.string()).default([]).description('Trusted client IP whitelist'),
// Numeric boundary constraints
rateLimitPerMinute: Schema.number().default(60).min(1).max(600).description('Maximum requests permitted per minute')
});
export function apply(ctx: Context, config: Config) {
console.log(`[Vault] Tier: ${config.environment}, Limit: ${config.rateLimitPerMinute} req/min`);
}
If a user forgets the mandatory masterApiKey or provides an unrecognized environment: 'test', Harness aborts startup immediately with detailed error paths, preventing silent production bugs.
Four Best Practices for Configuration Engineering
- Eliminate Hardcoded Constants: Move network timeouts, retry limits, and endpoints into configuration schemas;
- Mask Confidential Secrets: Chain
.role('secret')on all API keys and credentials; - Enforce Boundary Constraints: Use
.min(),.max(), and.union()to catch malformed values early; - Seamless Live Updates: Design plugins to handle dynamic configuration changes gracefully during hot reload.
Frequently Asked Questions (FAQ)
Q1: Why use Schemastery instead of standard TypeScript type assertions?
Answer: TypeScript interfaces are erased during compilation and cannot validate data at runtime. Schemastery provides both static TypeScript types and runtime validation with automatic default assignment.
Q2: What happens if undeclared fields are passed in cordis.yml?
Answer: Schemastery strips undeclared keys and logs diagnostic warnings, helping developers catch typographical errors (e.g. time_out instead of timeoutMs).
Q3: What is the exact behavior of .role('secret')?
Answer: When marked as a secret, values are masked as *** across Web UI dashboards, CLI dumps, and persisted Trajectory audit logs, preventing accidental credential exposure.
Q4: How does a plugin adapt to dynamic configuration edits in production?
Answer: In hot-reload environments (e.g. pnpm dsh web --patch), file changes trigger validation. Once verified, the microkernel updates the plugin Fiber branch with the fresh configuration.