@dcyfr/ai
v3.5.3
Published
Portable AI agent harness with plugin architecture
Downloads
688
Maintainers
Readme
Portable AI agent harness with plugin architecture for managing multiple AI providers, tracking telemetry, and ensuring quality compliance.
About DCYFR
@dcyfr/ai is maintained by DCYFR Labs as part of the DCYFR AI tooling portfolio.
- DCYFR is a registered trademark of DCYFR Labs.
- Primary domain: www.dcyfr.ai
- Licensing details: LICENSE
- Peerlist project: peerlist.io/dcyfr/project/dcyfr-ai
🔍 @dcyfr/ai vs. Alternatives
| Feature | @dcyfr/ai | LangChain | Vercel AI SDK | AutoGPT |
| -------------- | ------------------------------ | ---------- | ------------- | ------- |
| Multi-Provider | ✅ | ✅ | ✅ | ❌ |
| Plugin System | ✅ Custom | ✅ Complex | ❌ | ❌ |
| Telemetry | ✅ Built-in | ❌ | ❌ | ❌ |
| Zero Config | ✅ | ❌ | ✅ | ❌ |
| Bundle Size | | ~2.3MB | ~450KB | N/A |
| TypeScript | ✅ Strict | Partial | ✅ | ❌ |
| Quality Gates | ✅ | ❌ | ❌ | ❌ |
| Config System | YAML/JSON/package | Code-only | Code-only | JSON |
| Learning Curve | Low | High | Low | High |
📊 npm Statistics
- Weekly Downloads: Check npm stats
- Dependencies: 27 production dependencies
- Bundle Size: See badge above (
)
- TypeScript: Full type definitions included
- ESM Support: ✅ Full ESM modules with tree shaking
Table of Contents
- Features
- Installation
- Quick Start
- Configuration
- Architecture
- Plugin System
- CLI Commands
- Examples
- Documentation
- Contributing
- Troubleshooting
- FAQ
- Performance Benchmarks
- Security
- Known Limitations
- License & Sponsorship
Features
- 🔌 Plugin Architecture - Extensible validation system with custom agents
- 🔄 Multi-Provider Support - OpenAI, Anthropic, Ollama, Msty Vibe CLI Proxy, GitHub Copilot
- 🎯 Msty Vibe Integration - Unified multi-model routing with local OpenAI-compatible endpoint
- ⚙️ Configuration System - YAML/JSON config with three-layer merge
- 📊 Comprehensive Telemetry - Track usage, costs, quality metrics, performance
- ✅ Validation Harness - Quality gates with parallel/serial execution
Installation
npm install @dcyfr/aiCLI command name: the package is
@dcyfr/ai, but its command-line tool is invoked asdcyfr-ai— not@dcyfr/ai. After installing, runnpx dcyfr-ai <command>(or, without installing first,npx -p @dcyfr/ai dcyfr-ai <command>). Runningnpx @dcyfr/ai …fails with "could not determine executable to run" because the package ships several binaries.
Quick Start
1. Initialize Configuration
npx dcyfr-ai config:initThis creates a .dcyfr.yaml configuration file:
version: "1.0.0"
projectName: my-app
agents:
designTokens:
enabled: true
compliance: 0.90
barrelExports:
enabled: true
pageLayout:
enabled: true
targetUsage: 0.90
testData:
enabled: true2. Load and Use Configuration
import { loadConfig, ValidationFramework } from "@dcyfr/ai";
// Load configuration (auto-detects .dcyfr.yaml, .dcyfr.json, package.json)
const config = await loadConfig();
// Create validation framework
const framework = new ValidationFramework({
gates: config.validation.gates,
parallel: config.validation.parallel,
});
// Run validation
const report = await framework.validate({
projectRoot: config.project.root,
files: config.project.include,
config: config.agents,
});
console.log(`Validation: ${report.valid ? "PASS" : "FAIL"}`);3. Validate Configuration
# Validate current project config
npx dcyfr-ai config:validate
# Show full configuration
npx dcyfr-ai config:validate --verbose🔄 Migration Guides
Migrating from LangChain
Why migrate: Smaller bundle footprint than LangChain (see bundlephobia), built-in telemetry, simpler API
// LangChain (before)
import { ChatOpenAI } from "langchain/chat_models/openai";
import { HumanMessage } from "langchain/schema";
const model = new ChatOpenAI({ temperature: 0.9 });
const response = await model.call([new HumanMessage("Hello")]);
// @dcyfr/ai (after)
import {
AgentRuntime,
ProviderRegistry,
TelemetryEngine,
getMemory,
} from "@dcyfr/ai";
const runtime = new AgentRuntime(
"assistant",
new ProviderRegistry({
primaryProvider: "anthropic",
fallbackChain: ["anthropic", "ollama"],
autoReturn: true,
healthCheckInterval: 60_000,
}),
getMemory(),
new TelemetryEngine(),
);
const result = await runtime.execute({ task: "Hello" });
console.log(result.output);Key Differences:
- Simpler configuration (YAML/JSON vs code-only)
- Built-in telemetry tracking (no additional setup)
- Smaller bundle size than LangChain (see bundlephobia)
- Type-safe validation with Zod
- Quality gates included out of the box
Migrating from Vercel AI SDK
Why migrate: Quality gates, telemetry, multi-provider validation harness
// Vercel AI SDK (before)
import { openai } from "@ai-sdk/openai";
import { generateText } from "ai";
const { text } = await generateText({
model: openai("gpt-4-turbo"),
prompt: "Hello",
});
// @dcyfr/ai (after)
import {
AgentRuntime,
ProviderRegistry,
TelemetryEngine,
ValidationFramework,
getMemory,
} from "@dcyfr/ai";
const runtime = new AgentRuntime(
"assistant",
new ProviderRegistry({
primaryProvider: "anthropic",
fallbackChain: ["anthropic", "ollama"],
autoReturn: true,
healthCheckInterval: 60_000,
}),
getMemory(),
new TelemetryEngine(),
);
const result = await runtime.execute({ task: "Hello" });
console.log(result.output);
// Bonus: Built-in validation
const validator = new ValidationFramework();
const report = await validator.validate({
/* ValidationContext */
});Key Differences:
- Configuration system (YAML/JSON files)
- Validation harness with quality gates
- Comprehensive telemetry tracking
- Plugin system for custom validators
- Zero-config startup option
Full Migration Docs: See docs/migrations/ for detailed guides
Getting Started with AgentRuntime
AgentRuntime executes multi-step tasks against the provider registry, with memory retrieval, tool execution, and telemetry built in.
Prerequisites
# Node.js 20+ required (package.json engines; CI tests on Node 24)
node --version
# Install @dcyfr/ai
npm install @dcyfr/ai
# Optional: enable remote providers
export ANTHROPIC_API_KEY=your_anthropic_key # enables the "anthropic" provider
export GITHUB_TOKEN=your_github_token # enables the "github-models" provider1. Basic AgentRuntime Setup
AgentRuntime takes positional arguments: an agent name, a ProviderRegistry, a memory instance, a TelemetryEngine, and an optional RuntimeConfig.
import {
AgentRuntime,
ProviderRegistry,
TelemetryEngine,
getMemory,
} from "@dcyfr/ai";
// Initialize components
const providers = new ProviderRegistry({
primaryProvider: "anthropic",
fallbackChain: ["anthropic", "github-models", "ollama"],
autoReturn: true,
healthCheckInterval: 60_000,
});
const telemetry = new TelemetryEngine({
storage: "file",
basePath: "./data/telemetry",
});
const memory = getMemory(); // shared DCYFRMemoryImpl singleton (mem0 backend)
// Create runtime
const runtime = new AgentRuntime("assistant", providers, memory, telemetry, {
maxIterations: 10, // optional RuntimeConfig
timeout: 120_000,
});Memory:
DCYFRMemoryis exported as an interface type only. The concrete class isDCYFRMemoryImpl(no constructor options), andgetMemory()returns a shared singleton. The mem0 backend (vector DB, LLM, embedder) is configured via environment/config — see docs/MEMORY_SETUP.md.
2. Execute a Task
const result = await runtime.execute({
task: "Explain quantum computing briefly",
userId: "user-123", // optional: scopes memory retrieval
sessionId: "session-456", // optional: telemetry correlation
});
if (result.success) {
console.log("Output:", result.output);
console.log(`${result.iterations} iteration(s), $${result.cost.toFixed(4)}`);
} else {
console.error(`Failed (${result.outcome}):`, result.error);
}execute() takes a TaskContext (task, plus optional userId, sessionId, agentId, traceId, metadata, tools) and returns an AgentExecutionResult (success, output, error, outcome, executionTime, cost, iterations).
Memory retrieval, injection, and persistence happen automatically when memoryEnabled is on (the default); tune it via RuntimeConfig (memoryTimeout, memoryRelevanceThreshold, workingMemoryEnabled, persistWorkingMemory).
3. Tools
Pass tools in the task context; the runtime invokes them during its reasoning loop. Each tool's execute receives the input plus a ToolExecutionContext with shared working memory and a queryMemory helper.
import { readFile } from "node:fs/promises";
import { z } from "zod";
const result = await runtime.execute({
task: "Summarize the project README",
tools: [
{
name: "read_file",
description: "Read a UTF-8 file from disk",
schema: z.object({ path: z.string() }),
execute: async (input) => readFile((input as { path: string }).path, "utf8"),
},
],
});4. Hooks
Register hooks with beforeExecute() / afterExecute(). A before-hook receives a HookContext (agentName, task, userId, sessionId, timestamp) and rejects execution by throwing; after-hooks additionally receive the final AgentExecutionResult.
// Before-execution hook: throw to reject the task
runtime.beforeExecute(async (context) => {
console.log(`🚀 Starting task: ${context.task}`);
if (context.task.includes("sensitive")) {
throw new Error("Sensitive content detected");
}
});
// After-execution hook: observe the result
runtime.afterExecute(async (context, result) => {
console.log(
`✅ "${context.task}" → ${result.outcome} in ${result.executionTime}ms`,
);
});5. Runtime Events
Subscribe to lifecycle events (task start/finish, LLM calls, tool executions, memory retrieval):
const listener = (event: unknown) => console.log("runtime event:", event);
runtime.on(listener);
// ... later
runtime.off(listener);6. Telemetry Monitoring & Analysis
Use the TelemetryEngine instance you constructed the runtime with:
// Recent execution events recorded by the engine
const events = await telemetry.getEvents();
console.log(`Total events: ${events.length}`);
// Aggregate per-agent stats over a period
const stats = await telemetry.getAgentStats("anthropic", "30d");7. CLI Dashboard Commands
# View telemetry dashboard (cost summary + recent activity)
npx dcyfr-ai telemetry
# Filter by agent
npx dcyfr-ai telemetry --agent claude
# Scope to a time period (today, yesterday, week, month)
npx dcyfr-ai telemetry --period today
# Model usage breakdown
npx dcyfr-ai telemetry --breakdown models
# Runtime / provider validation
npx dcyfr-ai validate-runtime
# Export data to CSV
npx dcyfr-ai telemetry --export usage_data.csv8. Provider Setup
Providers register automatically inside ProviderRegistry; remote providers are enabled when their credentials/endpoints are present:
| Provider | Tier | Enabled by |
| --------------- | ------------------------------------- | ----------------------------------------------------------------- |
| local | 0 — local OpenAI-compatible endpoint | always (default LOCAL_LLM_BASE_URL = http://localhost:11973/v1) |
| ollama | 0 — local Ollama | always (default OLLAMA_HOST = http://localhost:11434) |
| workbench | 1 — private GPU node | WORKBENCH_BASE_URL set |
| github-models | 2 — GitHub Models | GITHUB_TOKEN set |
| anthropic | 3 — Anthropic API | ANTHROPIC_API_KEY set |
Fallback order follows the fallbackChain you pass to ProviderRegistry; with autoReturn: true the registry returns to the primary provider when it recovers.
# Ollama (local)
curl -fsSL https://ollama.ai/install.sh | sh
ollama pull llama3.2
export OLLAMA_HOST=http://localhost:11434 # optional custom host
# Anthropic
export ANTHROPIC_API_KEY=sk-ant-your-key-here
# GitHub Models
export GITHUB_TOKEN=your_github_token9. Configuration Examples
Development (no persistence):
const runtime = new AgentRuntime(
"dev-assistant",
new ProviderRegistry({
primaryProvider: "ollama",
fallbackChain: ["ollama", "local"],
autoReturn: false,
healthCheckInterval: 60_000,
}),
getMemory(),
new TelemetryEngine(), // defaults to in-memory storage
);Production (file-backed telemetry):
const runtime = new AgentRuntime(
"prod-assistant",
new ProviderRegistry({
primaryProvider: "anthropic",
fallbackChain: ["anthropic", "github-models", "ollama"],
autoReturn: true,
healthCheckInterval: 60_000,
}),
getMemory(),
new TelemetryEngine({ storage: "file", basePath: "./data/telemetry" }),
{ persistWorkingMemory: true },
);Telemetry storage supports the
"memory"and"file"adapters (or pass your ownStorageAdapter). Database-backed storage is not implemented yet — see Known Limitations.
Autonomous Agent Runtime
Build agents that operate independently with persistent memory, scheduled execution, platform messaging, and dynamic skill injection.
Subpath Imports
import {
FileMemoryAdapter,
SQLiteIndex,
flushWorkingMemory,
} from "@dcyfr/ai/memory";
import { ContextCompactor, MemoryCompaction } from "@dcyfr/ai/compaction";
import { SkillRegistry } from "@dcyfr/ai/skills";
import { MCPToolBridge } from "@dcyfr/ai/mcp";
import { SessionManager } from "@dcyfr/ai/session";
import { AgentScheduler } from "@dcyfr/ai/scheduler";
import { MessageGateway, TelegramAdapter, CLIAdapter } from "@dcyfr/ai/gateway";Key Capabilities
| Module | Description |
| ---------------------- | ------------------------------------------------------------------------------------------ |
| File Memory | Markdown-based persistent memory with SHA-256 dedup and optional SQLite FTS5 hybrid search |
| Context Compaction | LLM-powered pre-flush summarization to prevent context overflow |
| Skill Injection | BM25-powered matching of .md skill files to inject relevant knowledge |
| MCP Tool Bridge | Bridges MCP server tool discovery → AgentRuntime tools |
| Session Management | Trust-level tool policies (full/sandboxed/readonly), session lifecycle |
| Agent Scheduler | Built-in cron parser, webhooks, event subscriptions, quiet hours |
| Messaging Gateway | Telegram/CLI/HTTP adapters, input sanitization, rate limiting |
| Memory Compaction | Cross-backend dedup, monthly conversation summarization, stale fact archival |
| Working Memory | Persist Map<string, unknown> as human-readable Markdown |
Quick Example
import { MessageGateway, TelegramAdapter } from "@dcyfr/ai/gateway";
import { SessionManager } from "@dcyfr/ai/session";
import { AgentScheduler } from "@dcyfr/ai/scheduler";
// Create a messaging gateway with platform adapters
const gateway = new MessageGateway({
adapters: [new TelegramAdapter({ sendFn: telegramBot.sendMessage })],
trustRules: [
{ name: "admin", userIds: ["admin-id"], trustLevel: "full", priority: 10 },
],
});
// Schedule daily tasks
const scheduler = new AgentScheduler({
executor: async (task) => runAgent(task),
});
scheduler.schedule("0 9 * * *", { name: "morning-report" });
scheduler.start();Full guide: See docs/guides/autonomous-agent-guide.md
Complete example: See examples/autonomous-agent.ts
Architecture
The DCYFR AI harness follows a layered architecture with clear separation of concerns:
graph TB
A[Configuration Files] -->|Load & Merge| B[Config Loader]
B -->|Initialize| C[Plugin Registry]
C -->|Register| D[Validation Engine]
C -->|Register| E[Telemetry Engine]
D -->|Execute| F[Quality Gates]
E -->|Track| G[Storage Adapters]
B -->|Configure| H[CLI Interface]
H -->|Commands| I[User]
style A fill:#e1f5ff
style B fill:#fff3cd
style C fill:#d4edda
style D fill:#d4edda
style E fill:#d4edda
style H fill:#cfe2ff
style I fill:#f8d7daKey Components
- Config Loader: Three-layer merge system (defaults → project config → env vars)
- Plugin Registry: Manages custom and built-in validation agents
- Validation Engine: Executes quality gates in parallel or serial mode
- Telemetry Engine: Tracks usage, costs, quality metrics with pluggable storage
- CLI Interface: User-facing commands for config management and validation
Configuration
File Formats
Supports multiple configuration formats (auto-detected):
.dcyfr.yaml/.dcyfr.yml- YAML format (recommended).dcyfr.json/dcyfr.config.json- JSON formatpackage.json- Underdcyfrkey
Three-Layer Merge
Configuration is merged from three sources:
Framework Defaults → Project Config → Environment Variables
(built-in) (.dcyfr.yaml) (DCYFR_* vars)Environment Overrides
Override any config value with environment variables. DCYFR_<PATH> maps to the lowercased dot-path in the config (e.g. DCYFR_TELEMETRY_ENABLED → telemetry.enabled):
DCYFR_TELEMETRY_ENABLED=false
DCYFR_VALIDATION_PARALLEL=truePlugin System
Built-in Agents
DCYFR comes with specialized validation agents:
- Design Token Validator - Enforces design system compliance
- Barrel Export Checker - Ensures import conventions
- PageLayout Enforcer - Validates layout usage patterns
- Test Data Guardian - Prevents production data in tests
See @dcyfr/workspace-agents for specialized DCYFR agents.
Custom Plugins
import { PluginLoader } from "@dcyfr/ai";
const customPlugin = {
manifest: {
name: "my-validator",
version: "1.0.0",
description: "Custom validation logic",
},
async onValidate(context) {
// Your validation logic
return {
valid: true,
violations: [],
warnings: [],
};
},
};
const loader = new PluginLoader();
await loader.loadPlugin(customPlugin);CLI Commands
# Initialize configuration
npx dcyfr-ai config:init
npx dcyfr-ai config:init --format json
npx dcyfr-ai config:init --minimal
# Validate configuration
npx dcyfr-ai config:validate
npx dcyfr-ai config:validate --verbose
npx dcyfr-ai config:validate --config custom.yaml
# Show schema
npx dcyfr-ai config:schema
# Help
npx dcyfr-ai helpExamples
See examples/ directory:
Examples index - prerequisites and run commands
basic-usage.ts- Getting startedplugin-system.ts- Plugin developmentconfiguration.ts- Configuration usage
Documentation
- Getting Started
- Provider Integrations - OpenAI, Anthropic, Ollama, Msty Vibe CLI Proxy
- Memory Setup - Vector database and memory configuration
- Plugin Development
- API Reference
- TUI Dashboard
- Release Management - Publishing and versioning
- Quick Release Guide - TL;DR for releases
Plugin Marketplace Security
- WASM_PLUGIN_STARTER.md - WebAssembly plugin starter template
- WASM_MIGRATION_GUIDE.md - Migrate Docker plugins to WASM
Contributing
See CONTRIBUTING.md for contribution guidelines.
Release Process
We use release-please for automated versioning and publishing. Version bumps are derived from PR titles using conventional commits.
For contributors:
Make your PR title a conventional commit (feat: minor, fix:/deps:/perf: patch, feat!: major). Squash-merge is required so the PR title becomes the commit on main.
fix(memory): correct mem0 client retry semantics
feat(provider-registry): add GitHub Models provider
deps: bump @anthropic-ai/sdk to 0.95.2For maintainers:
- release-please opens a Release PR aggregating unreleased commits
- Merging the Release PR publishes to npm via OIDC Trusted Publishing
- See CONTRIBUTING.md for the full release flow
🔧 Troubleshooting
Installation Issues
Issue: npm install @dcyfr/ai fails with 404
- Cause: Package may not be published yet or npm registry issue
- Solution: Verify package exists:
npm view @dcyfr/ai, or install from GitHub:npm install git+https://github.com/dcyfr-labs/dcyfr-ai.git - Check: Visit https://www.npmjs.com/package/@dcyfr/ai to confirm publication status
Issue: "Cannot find module '@dcyfr/ai'"
- Cause: Package not in
node_modulesor incorrect import path - Solution: Run
npm install, verify import:import { loadConfig } from '@dcyfr/ai' - TypeScript: Ensure
moduleResolution: "bundler"or"node16"in tsconfig.json
Configuration Issues
Issue: .dcyfr.yaml not detected
- Cause: File in wrong location or invalid YAML syntax
- Solution:
- Place
.dcyfr.yamlin project root (same directory as package.json) - Validate YAML syntax with
npx dcyfr-ai config:validate - Check for tabs (use spaces), missing colons, incorrect indentation
- Place
- Alternative: Use
.dcyfr.jsonor adddcyfrkey topackage.json
Issue: "Invalid configuration schema"
- Cause: Missing required fields or incorrect types
- Solution:
- Run
npx dcyfr-ai config:schemato see full schema - Ensure required fields present:
version,projectName - Check types match (strings in quotes, booleans without quotes, arrays with brackets)
- Run
- Example: Valid config minimum:
version: "1.0.0"
projectName: my-appIssue: Environment variables not overriding config
- Cause: Incorrect env var naming or precedence
- Solution: Use
DCYFR_prefix with nested path:DCYFR_AGENTS_DESIGNTOKENS_COMPLIANCE=0.95 - Format:
DCYFR_<SECTION>_<SUBSECTION>_<KEY>=<value>(uppercase, underscores) - Debug: Log final config to see what values are being used
Plugin Issues
Issue: Custom plugin not loading
- Cause: Plugin doesn't implement required interface or missing manifest
- Solution: Ensure plugin exports:
manifestobject withname,version,descriptiononValidatemethod (async function)- Proper TypeScript types if using TypeScript
- Example: See examples/plugin-system.ts
Issue: Validation fails with "No plugins loaded"
- Cause: Plugins not registered with PluginLoader before validation
- Solution:
import { PluginLoader } from "@dcyfr/ai";
const loader = new PluginLoader();
await loader.loadPlugin(myPlugin);
await loader.runValidation();CLI Issues
Issue: npx @dcyfr/ai config:init fails with "could not determine executable to run"
- Cause: The CLI binary is named
dcyfr-ai, not@dcyfr/ai. The package ships two binaries (dcyfr-ai,dcyfr-ai-tui), sonpxcannot infer which onenpx @dcyfr/ai …should run. - Solution: Invoke the binary by name:
- After
npm install @dcyfr/ai:npx dcyfr-ai config:init - Without installing first:
npx -p @dcyfr/ai dcyfr-ai config:init - Global:
npm install -g @dcyfr/ai, thendcyfr-ai config:init
- After
Issue: CLI commands hang or timeout
- Cause: Large project or slow file system operations
- Solution:
- Use
--filesflag to target specific files:npx dcyfr-ai validate --files "src/**/*.ts" - Increase timeout in config:
timeout: 60000(60 seconds) - Check for infinite loops in custom plugins
- Use
📚 FAQ
Q: Is @dcyfr/ai published to npm?
A: Yes, it's published as a public package on npm. Install with npm install @dcyfr/ai. Check https://www.npmjs.com/package/@dcyfr/ai for latest version and stats.
Q: Can I use @dcyfr/ai with JavaScript (no TypeScript)?
A: Yes, but TypeScript is strongly recommended for better type safety and IDE support. The harness provides full TypeScript support with Zod validation for runtime type checking. If using JavaScript, you'll miss compile-time type checking but runtime validation still works.
Q: How do I create a custom validation plugin?
A: Implement the Plugin interface with manifest and onValidate method:
export const myPlugin = {
manifest: {
name: "my-plugin",
version: "1.0.0",
description: "My custom validation",
},
async onValidate(context) {
// Your validation logic here
return { passed: true, issues: [] };
},
};See docs/PLUGINS.md and examples/plugin-system.ts for complete guide.
Q: What's the difference between @dcyfr/ai and @dcyfr/workspace-agents?
A: @dcyfr/ai is the public harness (plugin architecture, config management, telemetry engine, validation harness). @dcyfr/workspace-agents is a private package with DCYFR-specific validation agents (design tokens, barrel exports, PageLayout enforcement). Think of @dcyfr/ai as the engine, @dcyfr/workspace-agents as pre-built plugins.
Q: Can I use this with other AI providers (non-Claude)?
A: Yes! The harness supports multi-provider integration including Claude, GitHub Copilot, Groq, Ollama, OpenAI, Anthropic. Configure providers in .dcyfr.yaml:
providers:
- name: openai
apiKey: ${OPENAI_API_KEY}
- name: anthropic
apiKey: ${ANTHROPIC_API_KEY}Q: How do I track telemetry and costs?
A: Use the TelemetryEngine with storage adapters:
import { TelemetryEngine, FileStorageAdapter } from "@dcyfr/ai";
const telemetry = new TelemetryEngine({
storage: new FileStorageAdapter("./telemetry"),
});Telemetry tracks: API calls, token usage, costs, latency, quality scores.
Q: Is this harness production-ready?
A: Yes! @dcyfr/ai is used in production at dcyfr-labs and other projects. It has comprehensive test coverage, semantic versioning, automated releases via release-please, and follows best practices for package publishing.
📊 Performance Benchmarks
Framework Performance
- Config Loading: ~10ms (cached), ~50ms (first load with file I/O)
- Validation Framework: Parallel execution 2-5x faster than serial (depends on plugin count)
- Plugin System: Minimal overhead ~5ms per plugin registration
- Bundle Size: See bundlephobia.com/@dcyfr/ai for current minzip size
Recommended Usage Patterns
- Use parallel validation for independent checks (faster):
mode: 'parallel' - Cache config loading (use singleton pattern): Load once, reuse across app
- Batch telemetry writes (reduce I/O overhead): Buffer writes, flush periodically
- Lazy load plugins (faster startup): Only load plugins you need for current validation
Comparison with Alternatives
- vs. Custom Scripts: 10-20x faster due to optimized plugin execution
- vs. Serial Validation: 2-5x faster with parallel execution mode
- vs. LangChain: Smaller bundle footprint (bundlephobia)
🔒 Security
Reporting Vulnerabilities
Found a security issue? Report it privately:
- GitHub Security Advisories: dcyfr-ai/security
- Expected Response: Within 48 hours
Security Considerations
- No API keys stored: Use environment variables for sensitive data (Zod validates but doesn't store)
- Zod validation: All inputs validated with schemas before processing
- No remote code execution: Plugins run in local environment only (no sandboxing yet - see limitations)
- Telemetry privacy: Optional, disable with
DCYFR_TELEMETRY_ENABLED=false - Dependencies: Regular Dependabot updates, npm audit on CI
Best Practices
- Never commit
.envfiles (use.env.example) - Use environment variables for API keys:
${OPENAI_API_KEY} - Review plugin code before loading (plugins have full access to filesystem)
- Keep dependencies updated:
npm outdated,npm update - Enable GitHub security scanning in your repository
⚙️ Known Limitations
Current Constraints
- Plugin isolation: Plugins run in same process (no sandboxing yet) - trust plugin code before loading
- File-based telemetry only: No database storage adapter yet (planned for v2.0)
- Config caching: Requires manual cache invalidation on config changes (no hot-reload yet)
- Provider-specific features: Some providers may have limited support (e.g., streaming not supported for all)
- TypeScript required for development: JavaScript works at runtime but TypeScript recommended for development
Platform-Specific Issues
- Windows: Path separators handled automatically but some plugins may have issues
- Node.js version: Requires ≥20.0.0 per
package.jsonengines (uses native fetch, modern APIs); CI tests on Node 24 - ESM-only: Package is ESM (ECMAScript Modules) - CommonJS require() not supported
Planned Improvements
- [ ] Database storage adapter for telemetry (PostgreSQL, SQLite)
- [ ] Plugin sandboxing for security (worker threads or VM isolation)
- [ ] Hot-reload config watching (auto-reload on file changes)
- [ ] Web UI for telemetry dashboard (view costs, usage, quality over time)
- [ ] Enhanced provider feature parity (streaming, function calling, vision)
- [ ] CommonJS compatibility mode (for legacy projects)
See GitHub Issues for tracked feature requests and bugs.
📄 License & Sponsorship
License: MIT. The LICENSE file is the canonical statement of this package's licensing terms.
Sponsorship
Development is supported through sponsorship — if @dcyfr/ai is useful to you or your business, consider sponsoring.
Join: GitHub Sponsors Contact: [email protected]
Trademark
"DCYFR" is a trademark of DCYFR Labs.
Made with ❤️ by DCYFR Labs
