Skip to content

@kernova/core

@kernova/core

The runtime kernel that powers every Kernova application. Like V8 is to Node.js, @kernova/core is to Kernova — it receives Intents and orchestrates their fulfillment through agents, tools, memory, and workflows.

Installation

Terminal window
npm install @kernova/core

Quick Start

import { KernovaKernel, defineAgent } from '@kernova/core';
const kernel = new KernovaKernel({
environment: 'development',
dataDir: './kernova-data',
models: { default: { provider: 'openai', model: 'gpt-4o' } },
});
await kernel.start();
const result = await kernel.submit({
goal: 'Summarize the latest sales report',
intentType: 'query',
});
console.log(result.result?.summary);
await kernel.stop();

KernovaKernel

The central orchestrator. Every other module is accessible through kernel accessor properties.

Constructor

const kernel = new KernovaKernel(config: KernelConfig);

KernelConfig

OptionTypeDefaultDescription
instanceIdstringauto-generatedUnique identifier for this kernel instance
environment'development' | 'staging' | 'production'—Required. Runtime environment
debugbooleanfalsePrint kernel and agent log() messages to the console
modelsModelRoutingConfigauto-detectedModel routing: default provider + purpose overrides. Auto-detection uses the first available provider and its own default model
providersModelProvider[][]Additional model providers. They replace auto-detected providers with the same ID
dataDirstring'./kernova-data'Directory for SQLite persistence
ephemeralbooleanfalseKeep everything in memory; nothing is written to disk
builtInToolsBuiltInToolConfigsafe tools onlyBuilt-in tools. shell-exec, code-eval, file-read, file-write, database-query are off unless listed in enabled
toolPolicyToolPolicy—Kernel-wide allow/deny lists of tool IDs (globs supported)
gatewayGatewayConfig—Settings for kernel.gateway
rateLimitsRateLimiterConfig100 requests/min per ownerPer-owner rate limits. The internal system owner is only limited by an explicit rule
eventRetentionDaysnumber30Delete persisted events older than this, at start and daily. 0 keeps them forever
reflectionobject{ enabled: false }Global self-reflection settings. Each reflection adds at least one model call per answer
threadHistorybooleantrueGive agents the earlier turns of an intent’s metadata.threadId and record each exchange. Turn off when your app keeps its own history
planningPartial<AgentPlannerConfig>—kernel.planner settings: maxSteps, strategy, adaptiveReplanning, maxReplanAttempts
ragPartial<RAGPipelineConfig>—kernel.rag settings: chunkSize, chunkOverlap, topK, scoreThreshold, chunkStrategy
identity{ sessionTtlSeconds? }24 hourskernel.identity settings
interface KernelConfig {
instanceId?: string;
environment: 'development' | 'staging' | 'production';
debug?: boolean;
models?: ModelRoutingConfig;
providers?: ModelProvider[];
dataDir?: string;
ephemeral?: boolean;
builtInTools?: BuiltInToolConfig;
toolPolicy?: ToolPolicy; // { allow?: string[]; deny?: string[] }
gateway?: GatewayConfig;
rateLimits?: RateLimiterConfig;
eventRetentionDays?: number; // default: 30 (0 = keep forever)
shutdownTimeoutMs?: number; // default: 10000
reflection?: {
enabled: boolean; // default: false
threshold?: number; // default: 0.7
maxAttempts?: number; // default: 2
};
threadHistory?: boolean; // default: true
planning?: Partial<AgentPlannerConfig>;
rag?: Partial<RAGPipelineConfig>;
identity?: { sessionTtlSeconds?: number };
}

Lifecycle

MethodSignatureDescription
start()() => Promise<void>Initialize all modules, open DB connections, begin event processing
stop()() => Promise<void>Graceful shutdown — refuses new intents, waits up to shutdownTimeoutMs for active ones, closes connections
submit()(intent) => Promise<Intent>Submit an intent for agent execution (primary entry point)
getStatus()() => KernelStatusReturns running state, active intents, providers, usage

submit()

The primary entry point. Accepts a partial intent with at minimum a goal string.

const result = await kernel.submit({
goal: 'Draft an email to the team about the release',
intentType: 'action', // 'query' | 'action' | 'observation'
priority: 'high', // 'critical' | 'high' | 'medium' | 'low'
owner: 'user-123', // scopes memory, budget and rate limits
metadata: { tag: 'comms', threadId: 'conversation-42' }, // threadId: include earlier turns
});
if (result.result?.success) {
console.log(result.result.summary);
}
  • owner can be any string, such as your app’s user ID. It scopes memory recall, budgets and rate limits. Owners registered with kernel.identity must also have the intent:submit permission. Without an owner, the intent runs as system.
  • metadata.threadId groups intents into a conversation: the agent sees earlier successful turns of the same thread (older turns are summarized). Without it, each intent is independent.
  • Retrieved documents from kernel.rag are added to the agent’s context automatically.

Accessor Properties

PropertyTypeDescription
kernel.eventsEventBusEvent pub/sub + persistence
kernel.memoryEngineMemoryEngineFive-layer memory system
kernel.agentRegistryAgentRegistryAgent management
kernel.modelsModelRouterModel routing & completions
kernel.pluginsPluginRegistryPlugin & tool management
kernel.workflowsWorkflowEngineMulti-step workflow execution
kernel.identityIdentityManagerAuth, users, permissions
kernel.budgetBudgetManagerToken budgets & cost caps
kernel.schedulerSchedulerCron & one-shot jobs
kernel.loopsBackgroundLoopModulePolling monitors
kernel.taskQueueTaskQueuePriority task queue
kernel.triggersProactiveTriggerEngineEvent-driven rules
kernel.channelsConnectorRegistryChannel adapters
kernel.plannerAgentPlannerPlan-and-execute
kernel.reflectionSelfReflectionQuality evaluation
kernel.conversationConversationManagerThread management
kernel.ragRAGPipelineDocument retrieval
kernel.mcpMCPBridgeModel Context Protocol
kernel.gatewayAgentGatewayHTTP API server
kernel.metricsMetricsCollectorRuntime metrics
kernel.healthHealthMonitorHealth checks
kernel.sandboxSandboxManagerIsolated execution
kernel.builtInToolsBuiltInToolRegistryBuilt-in tool access

EventBus

The nervous system of the runtime. Every state change, action, and decision flows through the EventBus as a structured event. Supports wildcard pattern matching, persistent storage via SQLite, timeline queries, and retention policies.

Key Exports

import { EventBus } from '@kernova/core';
import type { EventBusConfig, EventQuery, EventStoreStats } from '@kernova/core';

Methods

MethodSignatureDescription
publish(event)(event: KernovaEvent) => voidEmit an event to all matching subscribers + persist
subscribe(patterns, handler)(patterns: string[], handler) => stringSubscribe to events; returns subscription ID
unsubscribe(id)(id: string) => voidRemove a subscription
query(params)(params: EventQuery) => KernovaEvent[]Rich filtering (type, category, actor, time range)
getTimeline(subjectId)(subjectId: string, limit?: number) => KernovaEvent[]All events for a specific entity
getCorrelated(correlationId)(correlationId: string, limit?: number) => KernovaEvent[]Trace a full request flow
count(params?)(params?) => numberCount matching events
applyRetention(days)(retentionDays: number) => numberDelete events older than N days
flush()() => voidForce pending writes to disk

Pattern Matching

Wildcards work at each dot-separated segment:

PatternMatches
"intent.*"intent.created, intent.completed, intent.failed
"*.created"intent.created, agent.created, workflow.created
"*"Everything
"kernel.started"Exact match only

Example

// Subscribe to all intent lifecycle events
const subId = kernel.events.subscribe(['intent.*'], (event) => {
console.log(`[${event.eventType}] ${event.data.intentId}`);
});
// Subscribe to everything
kernel.events.subscribe(['*'], (event) => {
metrics.track(event.eventType);
});
// Query recent errors
const errors = kernel.events.query({
category: 'intent',
severity: 'error',
limit: 20,
order: 'desc',
});
// Get the full timeline of a specific intent
const timeline = kernel.events.getTimeline('intent-abc123');
// Clean up old events
const deleted = kernel.events.applyRetention(30); // keep 30 days
// Unsubscribe when done
kernel.events.unsubscribe(subId);

When to Use

  • Reacting to system events in real-time (webhooks, notifications, logging)
  • Auditing and compliance (full event history)
  • Debugging with correlation tracing
  • Building event-driven architectures on top of Kernova

MemoryEngine

A five-layer memory architecture inspired by human cognition. Combines SQLite FTS5 full-text search with vector embeddings for semantic retrieval.

Memory Layers

LayerPurposeTTL
workingCurrent task scratchpadMinutes
sessionCurrent conversation contextHours (default 3600s)
longtermPersistent user/agent knowledgeMonths/Years
organizationalShared team knowledgeIndefinite
globalSystem-wide factsIndefinite

Key Exports

import { MemoryEngine } from '@kernova/core';
import type { MemoryEngineConfig } from '@kernova/core';

Methods

MethodSignatureDescription
store(entry)(entry: MemoryEntry) => stringStore a memory; returns ID
query(query)(query: MemoryQuery) => MemoryEntry[]Search by text, tags, layer, time range
get(id)(id: string) => MemoryEntry | nullRetrieve a specific memory by ID
delete(id)(id: string) => booleanRemove a memory
decay(options?)(options?) => numberRun decay — expire working/session memories past TTL

Example

// Store a long-term memory
const memId = kernel.memoryEngine.store({
content: 'User prefers concise responses under 200 words',
layer: 'longterm',
tags: ['preference', 'style'],
owner: 'user-123',
});
// Semantic search across all layers
const results = kernel.memoryEngine.query({
text: 'communication preferences',
layer: 'longterm',
owner: 'user-123',
limit: 5,
});
// Store working memory (auto-expires)
kernel.memoryEngine.store({
content: 'Currently drafting Q4 report',
layer: 'working',
tags: ['task-context'],
});
// Manual decay pass (usually automatic)
const expired = kernel.memoryEngine.decay({ maxAge: 3600 });

When to Use

  • Giving agents context about past interactions
  • Storing user preferences and learned behaviors
  • Building organizational knowledge bases
  • Providing relevant context without exceeding token budgets

ModelRouter

Routes completion requests to the right model provider based on configurable rules. Supports purpose-based overrides, a fallback provider, streaming, embeddings, model listing, and 26 cataloged providers (see Model Providers).

Key Exports

import { ModelRouter, createProvider, detectAvailableProviders } from '@kernova/core';
import { AzureOpenAIProvider, BedrockProvider, VertexAIProvider } from '@kernova/core';
import type { ModelRouterConfig, ModelProvider } from '@kernova/core';

Methods

MethodSignatureDescription
complete(request, purpose?)(req, purpose?) => Promise<CompletionResponse>Single completion
stream(request, purpose?)(req, purpose?) => AsyncGenerator<StreamChunk>Streaming tokens
embed(text)(text: string) => Promise<number[]>Generate embedding vector
embedMany(texts)(texts: string[]) => Promise<number[][]>Embed several texts, batched where the provider allows
listModels(provider?)(provider?: string) => Promise<ModelInfo[]>Models a provider offers (all available providers without one)
getAvailableProviders()() => string[]IDs of the available providers
getUsageStats()() => { usage: TokenUsage; requestCount: number }Token counts (including cached and reasoning tokens) and costs
measureUsage(fn)(fn) => Promise<{ result, usage }>Tokens used by the model calls fn makes

Routing Configuration

const kernel = new KernovaKernel({
environment: 'production',
models: {
default: { provider: 'anthropic', model: 'claude-sonnet-5-5' },
// Per-purpose models: reasoning, generation, classification, extraction, conversation, vision, code, ...
overrides: {
code: { provider: 'anthropic', model: 'claude-sonnet-5-5' },
classification: { provider: 'openai', model: 'gpt-4o-mini' },
},
// Tried once when the default provider fails
fallback: { provider: 'openai', model: 'gpt-4o' },
},
});

Providers

Auto-detected from environment variables. The full list, with each provider’s variable and default model, is in Model Providers.

ClassAPIUsed for
OpenAIProviderOpenAIopenai
AzureOpenAIProviderAzure OpenAI v1 API (API key or Microsoft Entra ID)azure
AnthropicProviderAnthropic Messages APIanthropic
GeminiProviderGemini APIgemini
VertexAIProviderVertex AI (service account, gcloud ADC, metadata server, or express-mode key)vertex
BedrockProviderBedrock Converse API (Bedrock API key or SigV4-signed AWS credentials)bedrock
OllamaProviderOllamaollama
OpenAICompatibleProviderAny /chat/completions APIDeepSeek, Groq, Mistral, xAI, Qwen, Moonshot, Z.ai, Together, OpenRouter, Hugging Face, NVIDIA, Fireworks, and your own

GoogleAuth, AwsCredentialChain, and signAwsRequest() are exported for your own Google Cloud and AWS calls.

Creating Providers Manually

import { createProvider, OpenAICompatibleProvider } from '@kernova/core';
// From presets
const deepseek = createProvider('deepseek');
const ollama = createProvider('ollama', { defaultModel: 'mistral' });
// Custom OpenAI-compatible endpoint
const custom = new OpenAICompatibleProvider({
id: 'my-provider',
name: 'My LLM',
baseUrl: 'https://api.example.com/v1',
apiKey: process.env.MY_API_KEY!,
defaultModel: 'my-model',
});
// Cloud platforms
const bedrock = new BedrockProvider({ region: 'us-east-1' });
const vertex = new VertexAIProvider({ project: 'my-project' });
const azure = new AzureOpenAIProvider({ endpoint: 'https://my-resource.openai.azure.com' });

Request Options

Beyond messages, model, temperature, maxTokens, stopSequences, and tools, every provider takes:

FieldTypeDescription
responseFormatResponseFormat: { type: 'json' } or { type: 'json_schema', schema, name?, strict? }JSON output; the parsed value comes back in response.parsed
reasoning{ effort?, budgetTokens?, includeThoughts? }Reasoning controls; the reasoning comes back in response.reasoning
cachebooleanPrompt caching (Claude and Bedrock need it; others cache automatically)
parts (on a message)ContentPart[]Text, images, audio, and files ({ type: 'file', url, filename? })
providerData (on a message)Record<string, unknown>Copy of response.providerData for the assistant turn, sent back during tool use

Example

// Direct completion
const response = await kernel.models.complete({
messages: [
{ role: 'system', content: 'You are a helpful assistant.' },
{ role: 'user', content: 'Explain quantum computing briefly.' },
],
});
// Streaming
for await (const chunk of kernel.models.stream({
messages: [{ role: 'user', content: 'Write a poem about code' }],
}, 'creative')) {
process.stdout.write(chunk.content || '');
}
// Embeddings for semantic search
const vector = await kernel.models.embed('machine learning concepts');
const vectors = await kernel.models.embedMany(['first', 'second']);
// Structured output and reasoning
const { parsed } = await kernel.models.complete({
messages: [{ role: 'user', content: 'List three primes as JSON: { "primes": number[] }' }],
responseFormat: { type: 'json' },
reasoning: { effort: 'low' },
});
// What a provider offers
const models = await kernel.models.listModels('anthropic');

AgentRegistry

Manages agent definitions, selection, and execution. Handles the tool-calling loop, inter-agent delegation, and provides the AgentTools interface to agent executors.

Key Exports

import { AgentRegistry } from '@kernova/core';
import type { AgentExecutor, AgentTools } from '@kernova/core';

Methods

MethodSignatureDescription
register(definition, executor)(def, exec) => voidRegister an agent
unregister(id)(id: string) => voidRemove an agent
selectAgent(intent, context)(intent, ctx) => AgentInstance | nullFind best agent for an intent
execute(instance, intent, context)(agent, intent, ctx) => Promise<IntentResult>Run the agent
list()() => AgentDefinition[]All registered agents
count()() => numberNumber of registered agents

AgentTools Interface

Every agent executor receives a tools object with these capabilities:

MethodDescription
tools.complete(prompt)Plain LLM completion
tools.stream(prompt)Streaming LLM completion
tools.streamToString(prompt)Stream and collect full response
tools.completeWithTools(prompt)LLM completion with automatic tool-calling loop
tools.useTool(name, params)Invoke a specific tool directly
tools.listTools()List available tools for this agent
tools.delegate(agentId, goal)Delegate a sub-task to another agent
tools.ask(agentId, question)Ask another agent a question
tools.broadcast(goal)Send a goal to all agents
tools.remember(content, layer?, tags?)Store a memory
tools.recall(query, options?)Search memories
tools.emit(eventType, data)Publish an event
tools.log(message)Structured logging

Example

import { defineAgent } from '@kernova/core';
const assistant = defineAgent({
name: 'research-assistant',
description: 'Researches topics and provides summaries',
capabilities: [
{ id: 'research', name: 'Research', description: 'Web research', confidence: 0.9 },
],
tools: [{ toolId: 'web-search', name: 'web-search', purpose: 'Search the web', required: true }],
instructions: 'You are a research assistant. Search the web and provide concise summaries.',
});
kernel.agentRegistry.register(assistant.definition, assistant.executor);

defineAgent()

The developer-facing API for creating agents. Returns a { definition, executor } pair ready for registration. If no custom execute function is provided, uses a default LLM executor with automatic tool-calling.

Key Exports

import { defineAgent } from '@kernova/core';
import type { AgentSpec, DefinedAgent } from '@kernova/core';

AgentSpec Interface

interface AgentSpec {
name: string; // Agent name
description: string; // What the agent does
capabilities: Capability[]; // What it can handle
tools: ToolReference[]; // Tools it can use
instructions: string; // System prompt
execute?: (intent, context, tools: AgentTools) => Promise<IntentResult>; // Custom logic
reflection?: {
enabled: boolean;
threshold?: number; // Override global (default 0.7)
maxAttempts?: number; // Override global (default 2)
};
toolPolicy?: ToolPolicy; // Which tools this agent may call (on top of the kernel's)
model?: { provider?: string; model?: string }; // This agent's model (default: kernel routing)
temperature?: number; // Sent with this agent's model calls
maxTokens?: number; // Sent with this agent's model calls
reasoning?: ReasoningOptions; // { effort?, budgetTokens?, includeThoughts? }
responseFormat?: ResponseFormat; // JSON, optionally matching a schema
promptCache?: boolean; // Prompt caching for this agent's calls
}

model routes every call the agent makes: give a provider ID (its default model), a model ID (sent to the default provider), or both. The provider must be registered (auto-detected from its API key, or passed in providers).

Default LLM Executor Behavior

When no execute function is provided, the agent:

  1. Assembles instructions + context memories + intent goal into a prompt
  2. If tools are available → uses completeWithTools() (LLM decides which tools to call)
  3. If no tools → uses plain complete()
  4. Returns the response with confidence scoring

Example — Custom Executor

const codeReviewer = defineAgent({
name: 'code-reviewer',
description: 'Reviews code for bugs and style issues',
capabilities: [
{ id: 'review', name: 'Code Review', description: 'Analyzes code quality', confidence: 0.95 },
],
tools: [{ toolId: 'file-read', name: 'file-read', purpose: 'Read source files', required: true }],
instructions: 'You review code for correctness, performance, and style.',
async execute(intent, context, tools) {
const startTime = Date.now();
// Read the file to review
const file = await tools.useTool('file-read', { path: intent.goal });
// Get LLM analysis
const review = await tools.complete(
`Review this code:\n\n${file}\n\nProvide specific feedback.`
);
// Remember findings for future context
await tools.remember(`Reviewed code: ${intent.goal}`, 'session', ['review']);
return {
success: true,
summary: review,
data: review,
evidence: {
sources: [{ type: 'memory', ref: 'llm-response', label: 'Code review', consultedAt: new Date().toISOString() }],
confidence: 0.9,
reasoning: 'Automated code review completed',
},
durationMs: Date.now() - startTime,
};
},
});
kernel.agentRegistry.register(codeReviewer.definition, codeReviewer.executor);

PluginRegistry

Manages tools, middleware hooks, and plugin lifecycle. Plugins can provide tools (callable functions), middleware (request/response interceptors), or both.

Key Exports

import { PluginRegistry } from '@kernova/core';
import type { KernovaPlugin, ToolDefinition, MiddlewareHook } from '@kernova/core';

Methods

MethodSignatureDescription
register(plugin)(plugin: KernovaPlugin) => Promise<void>Register a plugin
unregister(id)(id: string) => voidRemove a plugin
listTools()() => ToolDefinition[]All available tools
executeTool(id, params)(id, params) => Promise<unknown>Execute a tool by ID
list()() => KernovaPlugin[]All registered plugins

Plugin Structure

interface KernovaPlugin {
id: string;
name: string;
version: string;
type: 'tool' | 'middleware' | 'integration';
tools?: ToolDefinition[];
middleware?: MiddlewareHook[];
onLoad?: (context: PluginContext) => Promise<void>;
onUnload?: () => Promise<void>;
}
interface ToolDefinition {
id: string;
name: string;
description: string;
parameters: JSONSchema; // JSON Schema for input validation
execute: (params: Record<string, unknown>) => Promise<unknown>;
}

Example

await kernel.plugins.register({
id: 'my-tools',
name: 'My Custom Tools',
version: '1.0.0',
type: 'tool',
tools: [
{
id: 'calculate',
name: 'Calculator',
description: 'Perform math calculations',
parameters: {
type: 'object',
properties: {
expression: { type: 'string', description: 'Math expression to evaluate' },
},
required: ['expression'],
},
execute: async (params) => {
const result = Function(`"use strict"; return (${params.expression})`)();
return { result };
},
},
],
});

WorkflowEngine

Executes multi-step workflows with support for parallel steps, conditional branching, approval gates, and compensation (rollback on failure).

Key Exports

import { WorkflowEngine } from '@kernova/core';
import type { WorkflowEngineConfig, ApprovalHandler } from '@kernova/core';

Methods

MethodSignatureDescription
define(definition)(def: WorkflowDefinition) => voidRegister a workflow
execute(definitionId, input?)(id: string, input?: object) => Promise<WorkflowInstance>Run a workflow and wait for it to finish
getInstance(instanceId)(id: string) => WorkflowInstance | undefinedA run’s status and step results
listDefinitions()() => WorkflowDefinition[]All registered workflows
listRunning()() => WorkflowInstance[]Runs in progress
onApproval(handler)(handler: ApprovalHandler) => voidDecide approval steps in code
resolveApproval(workflowId, stepId, approved, reason?)(...) => voidApprove or reject a waiting step
getPendingApprovals()() => Array<{ workflowId, stepId, stepName }>Steps waiting for approval

Example

Each step names its type and a config. Agent steps send config.input.goal (or the step name) to the agent named in config.agentId; steps don’t pass their output to the next step.

import { generateId, now } from '@kernova/core';
kernel.workflows.define({
id: 'content-pipeline',
type: 'workflow_definition',
version: '1.0.0',
owner: 'system',
status: 'active',
createdAt: now(),
updatedAt: now(),
metadata: {},
name: 'Content Pipeline',
description: 'Research, then approve, then publish',
steps: [
{
id: 'research',
name: 'Research the topic',
type: 'agent',
config: { agentId: 'research-assistant', input: { goal: 'Research AI in healthcare' } },
onFailure: 'stop',
},
{
id: 'review',
name: 'Editorial review',
type: 'approval',
config: { approvers: ['editor'] },
onFailure: 'stop',
},
{
id: 'publish',
name: 'Publish to CMS',
type: 'tool',
config: { toolId: 'cms:publish' },
onFailure: 'compensate',
compensation: { toolId: 'cms:unpublish' },
},
],
});
const instance = await kernel.workflows.execute('content-pipeline', { topic: 'AI in Healthcare' });
console.log(instance.workflowStatus, instance.stepResults);

With @kernova/sdk, the workflow(name, steps) helper fills in the boilerplate fields.

When to Use

  • Multi-step processes that require coordination between agents
  • Processes that need human approval at certain stages
  • Operations that need rollback/compensation on failure
  • Parallel task execution with dependency management

Scheduler

Runs jobs on cron schedules or after a one-shot delay. Persists schedules to survive restarts and detects missed executions.

Key Exports

import { Scheduler } from '@kernova/core';

Methods

MethodSignatureDescription
register(input)(input: ScheduledJobInput) => stringRegister a job; returns ID
remove(id)(id: string) => voidRemove a scheduled job
list()() => ScheduledJob[]All registered jobs
get(id)(id: string) => ScheduledJob | undefinedGet a specific job

ScheduledJobInput

interface ScheduledJobInput {
name: string;
cronExpression?: string; // e.g. '0 9 * * *' (daily at 9am)
delayMs?: number; // one-shot delay in milliseconds
oneShot?: boolean; // auto-disable after first fire
target: {
type: 'agent' | 'intent' | 'event';
id?: string;
goal?: string;
};
}

Example

// Daily standup summary at 9am
kernel.scheduler.register({
name: 'daily-standup',
cronExpression: '0 9 * * 1-5', // Mon-Fri at 9:00
target: {
type: 'agent',
id: 'standup-agent',
goal: 'Generate daily standup summary from yesterday\'s activity',
},
});
// One-shot reminder in 2 hours
kernel.scheduler.register({
name: 'follow-up-reminder',
delayMs: 2 * 60 * 60 * 1000,
oneShot: true,
target: {
type: 'intent',
goal: 'Remind user to follow up on the proposal',
},
});
// List all jobs
const jobs = kernel.scheduler.list();
console.log(`${jobs.length} scheduled jobs`);

When to Use

  • Recurring agent tasks (daily reports, weekly cleanups)
  • Delayed actions (reminders, follow-ups)
  • Periodic data synchronization
  • Any time-based automation

TaskQueue

A priority queue with concurrency control, exponential backoff retries, and dead-letter handling for failed tasks.

Key Exports

import { TaskQueue } from '@kernova/core';
import type { TaskQueueConfig, TaskHandler } from '@kernova/core';

Methods

MethodSignatureDescription
registerHandler(name, handler)(name, handler: TaskHandler) => voidRegister a task handler
enqueue(input)(input: TaskInput) => stringAdd a task; returns task ID
stats()() => QueueStatsQueue statistics
deadLetters(filter?)(filter?) => DeadLetter[]Get failed tasks
replay(id)(id: string) => voidRetry a dead-lettered task

Priority Levels

Tasks are processed in priority order:

PriorityValueUse Case
critical0System health, security alerts
high1User-facing requests
medium2Background processing (default)
low3Maintenance, analytics

Configuration

interface TaskQueueConfig {
concurrency?: number; // 1-50, default: 5
maxRetries?: number; // default: 3
backoffMs?: number; // initial backoff, default: 1000
maxBackoffMs?: number; // cap, default: 30000
deadLetterLimit?: number; // max dead letters kept
}

Example

// Register a handler
kernel.taskQueue.registerHandler('send-email', async (task) => {
const { to, subject, body } = task.payload;
await emailService.send(to, subject, body);
return { sent: true };
});
// Enqueue tasks with priority
kernel.taskQueue.enqueue({
handler: 'send-email',
payload: { to: 'team@company.com', subject: 'Alert', body: '...' },
priority: 'high',
});
kernel.taskQueue.enqueue({
handler: 'send-email',
payload: { to: 'analytics@company.com', subject: 'Weekly digest', body: '...' },
priority: 'low',
});
// Check stats
const stats = kernel.taskQueue.stats();
console.log(`Pending: ${stats.pending}, Active: ${stats.active}, Failed: ${stats.failed}`);
// Replay a failed task
const deadLetters = kernel.taskQueue.deadLetters();
if (deadLetters.length > 0) {
kernel.taskQueue.replay(deadLetters[0].id);
}

When to Use

  • Background job processing with guaranteed delivery
  • Rate-limiting expensive operations (API calls, file processing)
  • Prioritizing work when resources are limited
  • Reliable task execution with retry semantics

ProactiveTriggerEngine

Event-driven rules that fire actions when specific events occur. Supports cooldown periods and conditional execution.

Key Exports

import { ProactiveTriggerEngine } from '@kernova/core';
import type { TriggerEngineConfig } from '@kernova/core';

Methods

MethodSignatureDescription
register(input)(input: TriggerRuleInput) => stringRegister a trigger rule
remove(id)(id: string) => voidRemove a trigger
enable(id)(id: string) => voidEnable a disabled trigger
disable(id)(id: string) => voidTemporarily disable
list()() => TriggerRule[]All registered triggers

TriggerRuleInput

interface TriggerRuleInput {
name: string;
eventPattern: string; // Wildcard pattern: "intent.failed", "*.created"
action: {
goal: string; // What to execute when triggered
priority?: string;
};
cooldownMs?: number; // Minimum time between firings (min: 100ms)
condition?: (event) => boolean; // Programmatic condition
conditionDescription?: string; // Human-readable description
}

Example

// Auto-retry failed intents
kernel.triggers.register({
name: 'auto-retry-failures',
eventPattern: 'intent.failed',
action: {
goal: 'Analyze why intent {{event.data.intentId}} failed and suggest fixes',
priority: 'medium',
},
cooldownMs: 5000, // Don't fire more than once per 5 seconds
});
// Welcome new users
kernel.triggers.register({
name: 'welcome-new-user',
eventPattern: 'identity.created',
action: {
goal: 'Send a welcome message to the new user',
},
cooldownMs: 1000,
conditionDescription: 'Only for human users, not service accounts',
});
// Disable a trigger temporarily
kernel.triggers.disable('trigger-abc123');

When to Use

  • Automated responses to system events
  • Self-healing behaviors (retry on failure)
  • Notification triggers
  • Proactive agent behaviors based on system state changes

BackgroundLoopModule

Polling monitors that run at configurable intervals. Support pause/resume for graceful resource management.

Key Exports

import { BackgroundLoopModule } from '@kernova/core';

Methods

MethodSignatureDescription
register(loop)(loop: LoopDefinition) => stringRegister a background loop
remove(id)(id: string) => voidRemove a loop
pause(id)(id: string) => voidPause a running loop
resume(id)(id: string) => voidResume a paused loop
list()() => LoopInfo[]All registered loops

Example

// Monitor system health every 30 seconds
kernel.loops.register({
name: 'health-check',
intervalMs: 30000,
handler: async () => {
const status = kernel.getStatus();
if (status.activeIntents > 100) {
kernel.events.publish({
eventType: 'system.overloaded',
// ...
});
}
},
});
// Check for new emails every 5 minutes
kernel.loops.register({
name: 'email-poll',
intervalMs: 5 * 60 * 1000,
handler: async () => {
const newEmails = await emailClient.checkInbox();
for (const email of newEmails) {
await kernel.submit({ goal: `Process email: ${email.subject}` });
}
},
});

When to Use

  • Polling external services for changes
  • Periodic health checks and monitoring
  • Resource cleanup loops
  • Any recurring background task that doesn’t fit a cron schedule

ConnectorRegistry

kernel.channels manages connections to messaging platforms. You register a connector with its platform config; the registry creates the adapter, connects it (reconnecting with backoff when a connection drops), and emits channel.* events. See the Channels guide for each platform’s config.

Supported Channels

ChannelchannelTypeAdapter class
SlackslackSlackAdapter
DiscorddiscordDiscordAdapter
WhatsAppwhatsappWhatsAppAdapter
TelegramtelegramTelegramAdapter
EmailemailEmailAdapter
Microsoft TeamsteamsTeamsAdapter
SMS (Twilio)smsSmsAdapter
SignalsignalSignalAdapter
MatrixmatrixMatrixAdapter
IRCircIrcAdapter
Voice (Twilio)voiceVoiceAdapter
Push (FCM/APNs)pushPushAdapter
RSS/AtomrssRssAdapter

WebhookChannelAdapter and WebSocketChannelAdapter aren’t managed by the registry: use them directly (await adapter.connect()) or through the SDK’s app.channel().

Key Exports

import { ConnectorRegistry, SlackAdapter, WebhookChannelAdapter, WebSocketChannelAdapter } from '@kernova/core';
import type { ConnectorRegistryConfig, ChannelAdapter } from '@kernova/core';

Methods

MethodSignatureDescription
register(input)({ channelType, name, config }) => ConnectorDefAdd a connector; its config is validated
connect(connectorId)(id: string) => Promise<void>Start the adapter
disconnect(connectorId)(id: string) => Promise<void>Stop the adapter
send(request)({ connectorId, recipient?, message }) => Promise<OutboundMessageResult>Send a message through a connector, to recipient (an inbound message’s replyTo)
onMessage(handler)(handler: (msg: InboundMessage) => Promise<void> | void) => () => voidHandle inbound messages from every connector; returns an unsubscribe function
reply(message, content)(msg: InboundMessage, content: string | OutboundMessage) => Promise<OutboundMessageResult>Answer a message on its connector, to its replyTo
status()() => ConnectorStatus[]Connection state of every connector

Example

const slack = kernel.channels.register({
channelType: 'slack',
name: 'support-slack',
config: {
type: 'slack',
botToken: process.env.SLACK_BOT_TOKEN!,
signingSecret: process.env.SLACK_SIGNING_SECRET!,
},
});
await kernel.channels.connect(slack.id);
// Answer every message in the conversation it came from
kernel.channels.onMessage(async (msg) => {
const intent = await kernel.submit({ goal: msg.content, owner: msg.sender, metadata: { threadId: `${msg.connectorId}:${msg.replyTo}` } });
await kernel.channels.reply(msg, intent.result?.summary ?? '');
});
// Or send proactively
await kernel.channels.send({
connectorId: slack.id,
recipient: 'C024BE91L', // a Slack channel ID
message: { content: 'Deploy finished' },
});
console.log(kernel.channels.status()); // [{ name: 'support-slack', state: 'connected', ... }]

When to Use

  • Building multi-channel AI assistants
  • Receiving messages from Slack, Discord, or other platforms
  • Real-time communication via WebSocket
  • Webhook integrations with third-party services

DaemonRunner

Persistent execution mode for Kernova. Wraps the kernel with signal handling (SIGINT/SIGTERM), periodic heartbeat emission, graceful shutdown, config file loading, and hot-reload.

Key Exports

import { DaemonRunner } from '@kernova/core';
import type { DaemonConfig } from '@kernova/core';

DaemonConfig

OptionTypeDefaultDescription
configPathstring—Path to agent config file or directory
watchbooleanfalseEnable hot-reload of config files
portnumber—Port for webhook/gateway listeners
dataDirstring—Data directory override
shutdownTimeoutMsnumber30000Max wait for active intents on shutdown
heartbeatIntervalMsnumber60000Heartbeat event interval

Methods

MethodSignatureDescription
start()() => Promise<void>Start daemon (resolves when stopped)
stop()() => Promise<void>Graceful shutdown
isRunning()() => booleanCheck if running
getLoadedConfigs()() => Map<string, AgentConfigFile>Get loaded agent configs

Example

import { KernovaKernel, DaemonRunner } from '@kernova/core';
const kernel = new KernovaKernel({
environment: 'production',
dataDir: '/var/lib/kernova',
});
await kernel.start();
const daemon = new DaemonRunner(kernel, {
configPath: './agents/',
watch: true,
shutdownTimeoutMs: 15000,
heartbeatIntervalMs: 30000,
});
// This blocks until SIGINT/SIGTERM is received
await daemon.start();
// Graceful shutdown has completed here

When to Use

  • Running Kernova as a long-lived background service
  • Production deployments that need signal handling
  • Loading agents from YAML/JSON config files with hot-reload
  • Server processes that need heartbeat monitoring

AgentPlanner

Implements the Plan-and-Execute pattern: decompose a complex goal into steps, execute them sequentially, and adaptively replan on failure.

Key Exports

import { AgentPlanner } from '@kernova/core';
import type { AgentPlannerConfig, StepExecutor } from '@kernova/core';

Methods

MethodSignatureDescription
plan(goal, context?)(goal, ctx?) => Promise<Plan>Generate a multi-step plan
execute(plan, executor)(plan, exec) => Promise<PlanResult>Execute all steps
cancel(planId)(planId: string) => voidCancel a running plan

Configuration

  • maxSteps: Maximum steps per plan (default: 10)
  • Adaptive replanning: If a step fails, the planner can revise remaining steps

Example

// Plan a complex task
const plan = await kernel.planner.plan(
'Migrate the users database from PostgreSQL to MongoDB',
{ constraints: ['zero downtime', 'data validation required'] }
);
console.log(`Plan has ${plan.steps.length} steps`);
plan.steps.forEach((step, i) => {
console.log(` ${i + 1}. ${step.description}`);
});
// Execute with a custom step executor
const result = await kernel.planner.execute(plan, async (step) => {
return kernel.submit({ goal: step.description, priority: 'high' });
});
if (result.success) {
console.log('Migration completed successfully');
}

When to Use

  • Complex multi-step tasks that need decomposition
  • Tasks where later steps depend on earlier results
  • Scenarios requiring adaptive replanning on failure
  • When you want the LLM to reason about approach before acting

SelfReflection

Quality evaluation and regeneration loop. After an agent produces output, SelfReflection scores it against the original goal and optionally regenerates if below the confidence threshold.

Key Exports

import { SelfReflection, clampConfidence, resolveReflectionConfig } from '@kernova/core';
import type { SelfReflectionConfig, ReflectionToggleConfig } from '@kernova/core';

Methods

MethodSignatureDescription
reflect(output, goal, context?, agentId?)(...) => Promise<ReflectionResult>Evaluate + optionally regenerate
evaluate(output, goal, context?)(...) => Promise<EvaluationResult>Score without regeneration

Configuration

OptionDefaultDescription
enabledtrueEnable/disable globally
threshold0.7Minimum confidence to accept output
maxAttempts2Max regeneration attempts

Utility Functions

  • clampConfidence(score) — Clamp a confidence score to [0, 1]
  • resolveReflectionConfig(global, agent?) — Merge global + per-agent reflection settings

Example

// Evaluate an agent's output
const evaluation = await kernel.reflection.evaluate(
agentOutput,
'Write a professional email to decline the meeting',
{ tone: 'polite but firm' }
);
console.log(`Confidence: ${evaluation.confidence}`);
console.log(`Feedback: ${evaluation.feedback}`);
// Full reflect loop (evaluate + regenerate if needed)
const result = await kernel.reflection.reflect(
agentOutput,
'Write a professional email to decline the meeting',
{ tone: 'polite but firm' },
'email-agent'
);
if (result.regenerated) {
console.log('Output was regenerated for higher quality');
console.log(result.finalOutput);
}

When to Use

  • Ensuring output quality for user-facing responses
  • Building self-improving agents that learn from feedback
  • Quality gates before publishing content
  • Confidence scoring for decision-making pipelines

ConversationManager

Manages named conversation threads with sliding window context, automatic summarization when the window is exceeded, and thread archival.

Key Exports

import { ConversationManager } from '@kernova/core';
import type { ConversationManagerConfig } from '@kernova/core';

Methods

MethodSignatureDescription
create(threadId)(id: string) => ThreadCreate a new thread
retrieve(threadId)(id: string) => Thread | nullGet an existing thread
archive(threadId)(id: string) => voidArchive a thread
addMessageToThread(threadId, role, content)(...) => voidAdd a message
getThreadContext(threadId)(id) => Message[]Get windowed messages
addMessage(role, content)(role, content) => Promise<void>Add to default thread

Configuration

OptionDefaultDescription
windowSize50Maximum messages in the sliding window
autoSummarizetrueSummarize older messages when window is exceeded

Example

// Create a named conversation thread
kernel.conversation.create('support-ticket-456');
// Add messages
kernel.conversation.addMessageToThread('support-ticket-456', 'user',
'My deployment is failing with exit code 137');
kernel.conversation.addMessageToThread('support-ticket-456', 'assistant',
'Exit code 137 indicates an OOM kill. Let me check your memory limits...');
// Get windowed context (respects sliding window + summarization)
const context = kernel.conversation.getThreadContext('support-ticket-456');
// Archive when done
kernel.conversation.archive('support-ticket-456');

When to Use

  • Multi-turn conversations with context management
  • Keeping conversation history within token budgets
  • Support ticket / thread-based interactions
  • Any long-running conversation that needs summarization

RAGPipeline

Retrieval-Augmented Generation pipeline. Ingest documents, chunk them with configurable strategies, and retrieve relevant context for agent prompts.

Key Exports

import { RAGPipeline } from '@kernova/core';
import type { RAGPipelineConfig } from '@kernova/core';

Methods

MethodSignatureDescription
ingest(content, source, metadata?)(...) => Promise<string>Ingest a document; returns doc ID
retrieve(query, options?)(query, opts?) => Promise<Chunk[]>Retrieve relevant chunks
getContext(query, options?)(query, opts?) => Promise<string>Get pre-formatted context string
remove(docId)(id: string) => Promise<void>Remove an ingested document
stats()() => RAGStatsDocument/chunk counts

Chunking Strategies

StrategyDescription
fixedFixed character-length chunks
recursiveRecursive splitting on separators (paragraphs → sentences → words)
sentenceSplit on sentence boundaries
paragraphSplit on paragraph boundaries

Example

// Ingest documentation
await kernel.rag.ingest(
fs.readFileSync('./docs/architecture.md', 'utf-8'),
'architecture.md',
{ category: 'docs', version: '2.0' }
);
await kernel.rag.ingest(
fs.readFileSync('./docs/api-reference.md', 'utf-8'),
'api-reference.md',
{ category: 'docs', version: '2.0' }
);
// Retrieve relevant context for a query
const chunks = await kernel.rag.retrieve('How does authentication work?', {
topK: 5,
threshold: 0.7,
});
chunks.forEach(chunk => {
console.log(`[${chunk.source}] Score: ${chunk.score}`);
console.log(chunk.content);
});
// Or get a pre-formatted context string
const context = await kernel.rag.getContext('authentication flow', { topK: 3 });
// Check stats
const stats = kernel.rag.stats();
console.log(`${stats.documents} documents, ${stats.chunks} chunks indexed`);

When to Use

  • Providing agents with relevant documentation context
  • Building knowledge bases from existing documents
  • Grounding agent responses in source material
  • Reducing hallucination by supplying factual context

Built-in Tools

Kernova ships with a set of built-in tools that are automatically registered when the kernel starts. Each tool is sandboxed and configurable.

Key Exports

import { BuiltInToolRegistry, SandboxViolationError } from '@kernova/core';
import type { BuiltInToolConfig } from '@kernova/core';

Available Tools

Tool IDDescription
http-fetchMake HTTP requests (GET, POST, PUT, DELETE, PATCH) with configurable timeout
file-readRead file contents (sandboxed to sandboxDir)
file-writeWrite file contents (sandboxed to sandboxDir)
shell-execExecute shell commands (with timeout, sandboxed)
date-timeGet current date/time in various formats and timezones
web-searchSearch the web (requires a WebSearchProvider implementation)

Configuration

interface BuiltInToolConfig {
enabled?: string[]; // Whitelist specific tools
disabled?: string[]; // Blacklist specific tools
sandboxDir?: string; // Root directory for file operations
shellTimeout?: number; // Shell command timeout in ms
}

Sandbox Enforcement

File operations (file-read, file-write) are restricted to the configured sandboxDir. Path traversal attempts (e.g., ../../etc/passwd) throw a SandboxViolationError.

Example

const kernel = new KernovaKernel({
environment: 'development',
builtInTools: {
enabled: ['http-fetch', 'file-read', 'date-time'], // Only these tools
sandboxDir: './workspace',
shellTimeout: 10000,
},
});
// Tools are automatically available to agents
// In a custom agent executor:
async execute(intent, context, tools) {
// Fetch external data
const response = await tools.useTool('http-fetch', {
url: 'https://api.example.com/data',
method: 'GET',
timeout: 5000,
});
// Read a local file
const content = await tools.useTool('file-read', {
path: 'notes.md',
});
// Get current time
const now = await tools.useTool('date-time', {
timezone: 'America/New_York',
format: 'iso',
});
}

http-fetch Details

// Parameters
{
url: string; // Required — the URL to fetch
method?: string; // GET, POST, PUT, DELETE, PATCH (default: GET)
headers?: object; // HTTP headers
body?: string; // Request body (for POST/PUT/PATCH)
timeout?: number; // Timeout in ms (default: 30000)
}
// Returns
{
status: number;
statusText: string;
headers: Record<string, string>;
body: string;
}

IdentityManager

Manages users, agents, services, API keys, sessions, permissions, and organizations.

Key Exports

import { IdentityManager, ApiKeyManager, PermissionEngine, SessionManager } from '@kernova/core';
import type {
RegisteredIdentity, Organization, ActorType,
ApiKey, CreateKeyOptions,
PermissionCheck, PermissionResult, Role,
Session, CreateSessionOptions,
} from '@kernova/core';

Sub-modules

Sub-moduleAccessorDescription
IdentityManagerkernel.identityCore identity CRUD
ApiKeyManagervia identityAPI key creation, validation, revocation
PermissionEnginevia identityRole-based permission checks
SessionManagervia identitySession creation, validation, expiry

Key Methods

MethodDescription
registerIdentity(options)Register a user, agent, or service identity ({ type, name, email?, roles? }; the ID is generated)
getIdentity(id)Get identity by ID
checkPermission(check)Check if an identity has a permission
createApiKey(options)Create an API key for an identity
authenticateWithKey(key)Resolve an API key to its identity and permissions (null if invalid)
createSession(options)Create a session for an identity
authenticateWithSession(token)Resolve a session token to its identity (null if invalid or expired)

Actor Types

  • user — Human users
  • agent — AI agents
  • service — Service accounts / integrations

Example

// Register a user (the ID is generated)
const alice = kernel.identity.registerIdentity({
type: 'user',
name: 'Alice',
email: 'alice@company.com',
roles: ['admin'],
});
// Check permissions before executing
const check = kernel.identity.checkPermission({
identityId: alice.id,
resource: 'intent',
action: 'submit',
});
if (!check.granted) {
throw new Error(`Permission denied: ${check.reason}`);
}
// The kernel automatically enforces permissions in submit()

When to Use

  • Multi-user Kernova deployments
  • API key-based authentication for external access
  • Role-based access control (admin, user, viewer)
  • Organization-level isolation

BudgetManager

Token budgets, cost caps, and rate limiting per identity. Prevents runaway costs by blocking requests that exceed configured limits.

Key Exports

import { BudgetManager } from '@kernova/core';
import type { BudgetConfig, IdentityBudget, BudgetCheckResult } from '@kernova/core';

Methods

MethodSignatureDescription
setGlobalBudget(config)(config: BudgetConfig) => voidSet system-wide budget
setIdentityBudget(id, budget)(id, budget) => voidSet per-identity budget
check(id, tokens?)(id, tokens?) => BudgetCheckResultCheck if request is allowed
record(id, tokens)(id, tokens: number) => voidRecord token usage

BudgetConfig

interface BudgetConfig {
maxTokens?: number; // Total token budget
maxCostUsd?: number; // Cost cap in USD
maxTokensPerIntent?: number; // Per-request token limit
requestsPerMinute?: number; // Rate limit
}

Example

// Set a global daily budget
kernel.budget.setGlobalBudget({
maxTokens: 1_000_000,
maxCostUsd: 50.00,
requestsPerMinute: 60,
});
// Set a per-user budget
kernel.budget.setIdentityBudget('user-123', {
maxTokens: 100_000,
maxTokensPerIntent: 4096,
requestsPerMinute: 10,
});
// Check before expensive operations
const check = kernel.budget.check('user-123', 2000);
if (!check.allowed) {
console.log(`Budget exceeded: ${check.reason}`);
// The kernel does this automatically in submit()
}
// Record actual usage (also automatic after submit)
kernel.budget.record('user-123', 1523);

When to Use

  • Controlling costs in production
  • Per-user or per-team token allocation
  • Preventing abuse in multi-tenant setups
  • Rate limiting expensive model calls

AgentGateway

An HTTP API server that exposes kernel capabilities over REST. Includes an OpenAI-compatible /v1/chat/completions endpoint for drop-in replacement.

Key Exports

import { AgentGateway } from '@kernova/core';
import type { GatewayConfig, GatewayAuthConfig } from '@kernova/core';

Methods

MethodSignatureDescription
start(config?)(config?: GatewayConfig) => Promise<void>Start the HTTP server. config overrides the settings from the constructor or KernelConfig.gateway. Throws if no token is configured and auth.allowAnonymous isn’t set
stop()() => Promise<void>Stop the server

Configuration

OptionDefaultDescription
port3000Port to listen on
host'127.0.0.1'Interface to bind
auth.tokens[KERNOVA_API_KEY] if setBearer tokens that grant access
auth.allowAnonymousfalseSkip authentication (local development only)
corsfalsefalse, true (any origin), or a list of allowed origins
maxBodyBytes1_048_576Request body size limit

Endpoints

MethodPathDescription
GET/healthHealth check
POST/v1/intentsSubmit an intent
POST/v1/chat/completionsOpenAI-compatible chat endpoint
POST/hooks/:pathWebhook receiver

Authentication

All endpoints require a Bearer token in the Authorization header, checked against auth.tokens (or KERNOVA_API_KEY). Webhook routes registered with a secret are authenticated by their HMAC signature instead.

Example

// Start the gateway with a token
await kernel.gateway.start({ auth: { tokens: [process.env.GATEWAY_TOKEN!] } });
// From external clients:
// curl -X POST http://localhost:3000/v1/intents \
// -H "Authorization: Bearer sk-xxx" \
// -H "Content-Type: application/json" \
// -d '{"goal": "Summarize today'\''s news", "priority": "medium"}'
// OpenAI-compatible endpoint (works with any OpenAI SDK):
// curl -X POST http://localhost:3000/v1/chat/completions \
// -H "Authorization: Bearer sk-xxx" \
// -H "Content-Type: application/json" \
// -d '{"model": "kernova", "messages": [{"role": "user", "content": "Hello"}]}'

When to Use

  • Exposing Kernova as an API service
  • Drop-in replacement for OpenAI API
  • Receiving webhooks from external services
  • Building UIs that talk to Kernova over HTTP

MCPBridge

Model Context Protocol integration. Connect to external MCP servers (via stdio or SSE transport) and expose their tools to Kernova agents.

Key Exports

import { MCPBridge } from '@kernova/core';
import type { MCPBridgeConfig } from '@kernova/core';

Methods

MethodSignatureDescription
register(config)(config: MCPServerConfig) => voidRegister an MCP server definition
connect(serverId)(id: string) => Promise<void>Connect to a registered server
callTool(serverId, toolName, args)(...) => Promise<unknown>Call a tool on an MCP server
getAllTools()() => MCPTool[]List all tools from all connected servers
disconnect(serverId)(id: string) => Promise<void>Disconnect from a server
dispose()() => Promise<void>Disconnect all and clean up

Supported Transports

TransportDescription
stdioSpawn a child process and communicate over stdin/stdout
sseConnect to a server-sent events endpoint over HTTP

Example

// Register an MCP server
kernel.mcp.register({
id: 'filesystem',
name: 'Filesystem MCP',
transport: 'stdio',
command: 'npx',
args: ['-y', '@modelcontextprotocol/server-filesystem', '/path/to/workspace'],
});
// Connect
await kernel.mcp.connect('filesystem');
// List available tools
const tools = kernel.mcp.getAllTools();
tools.forEach(t => console.log(`${t.name}: ${t.description}`));
// Call a tool directly
const result = await kernel.mcp.callTool('filesystem', 'read_file', {
path: '/path/to/file.txt',
});
// MCP tools are also automatically available to agents via the tool-calling loop
// Clean up
await kernel.mcp.disconnect('filesystem');

When to Use

  • Integrating with the MCP ecosystem (filesystem, databases, APIs)
  • Extending Kernova with tools from third-party MCP servers
  • Building bridges between Kernova and other AI tools
  • Using existing MCP server implementations without rewriting

MetricsCollector

Collects runtime metrics including token usage, request counts, latencies, and custom metrics. Provides periodic snapshots.

Key Exports

import { MetricsCollector } from '@kernova/core';
import type { MetricsSnapshot, MetricEntry, MetricsConfig } from '@kernova/core';

Methods

MethodSignatureDescription
start()() => voidBegin collecting metrics
stop()() => voidStop collection
record(name, value, tags?)(...) => voidRecord a custom metric
snapshot()() => MetricsSnapshotGet current metrics snapshot
reset()() => voidReset all counters

Example

// Metrics auto-start with the kernel (if debug: true)
kernel.metrics.start();
// Record custom metrics
kernel.metrics.record('custom.operation.duration', 1523, { operation: 'sync' });
// Get a snapshot
const snapshot = kernel.metrics.snapshot();
console.log(`Total requests: ${snapshot.totalRequests}`);
console.log(`Total tokens: ${snapshot.totalTokens}`);
console.log(`Avg latency: ${snapshot.avgLatencyMs}ms`);

When to Use

  • Monitoring production deployments
  • Tracking token usage over time
  • Custom business metrics
  • Integration with observability platforms (Datadog, Prometheus)

HealthMonitor

Health check system with configurable checks and polling. Reports overall system health as healthy, degraded, or unhealthy.

Key Exports

import { HealthMonitor } from '@kernova/core';
import type { HealthStatus, HealthCheck, HealthMonitorConfig } from '@kernova/core';

Methods

MethodSignatureDescription
addCheck(check)(check: HealthCheck) => voidRegister a health check
removeCheck(id)(id: string) => voidRemove a check
check()() => HealthStatusRun all checks and return status
startPolling(intervalMs)(ms: number) => voidBegin periodic checks
stopPolling()() => voidStop periodic checks

Built-in Checks

The kernel automatically registers:

  • Kernel Running — Is the kernel started?
  • Model Providers — Are model providers available?

Example

// Add a custom health check
kernel.health.addCheck({
id: 'database',
name: 'Database Connection',
check: async () => {
try {
await db.ping();
return { state: 'healthy', message: 'Connected' };
} catch (e) {
return { state: 'unhealthy', message: e.message };
}
},
});
// Run all checks
const status = kernel.health.check();
console.log(`Overall: ${status.state}`); // 'healthy' | 'degraded' | 'unhealthy'
status.checks.forEach(c => {
console.log(` ${c.name}: ${c.state}`);
});
// Poll every 30 seconds (emits events on state changes)
kernel.health.startPolling(30000);

When to Use

  • Load balancer health endpoints
  • Monitoring system dependencies
  • Alerting on degraded state
  • Kubernetes liveness/readiness probes

SandboxManager

Policy checks for agent runs: which paths, tools, network, and writes are allowed. It decides; it does not isolate processes.

Key Exports

import { SandboxManager } from '@kernova/core';
import type { SandboxConfig, SandboxPolicy } from '@kernova/core';

Methods

Policies are checked per context: create one for an agent’s run, then ask it before acting. The built-in file and shell tools enforce their own sandbox (builtInTools.sandboxDir); this manager is for your own tools and checks.

MethodSignatureDescription
createContext(agentId, policy?)(id: string, policy?: Partial<SandboxPolicy>) => SandboxContextStart a sandbox context with a policy
isPathAllowed(contextId, path)(id: string, path: string) => booleanWhether a path is inside the workspace and not denied
isToolAllowed(contextId, tool)(id: string, tool: string) => booleanCheck the policy’s allowed/denied tools
isWriteAllowed(contextId) / isNetworkAllowed(contextId)(id: string) => booleanCheck the policy’s write and network flags
getTimeout(contextId)(id: string) => numberThe policy’s timeout in ms
destroy(contextId)(id: string) => voidEnd a context

SandboxPolicy: allowedPaths, deniedPaths, allowedTools, deniedTools, timeoutMs, allowNetwork, allowWrite.

Example

const sandbox = kernel.sandbox.createContext('report-writer', {
deniedTools: ['shell-exec'],
allowNetwork: false,
});
kernel.sandbox.isPathAllowed(sandbox.id, 'reports/q3.md'); // true
kernel.sandbox.isPathAllowed(sandbox.id, '../../etc/passwd'); // false (emits sandbox.path.denied)
kernel.sandbox.isToolAllowed(sandbox.id, 'shell-exec'); // false
kernel.sandbox.destroy(sandbox.id);

When to Use

  • Restricting agent file access to a workspace
  • Preventing path traversal attacks
  • Enforcing security policies on tool execution

Testing Utilities

Dedicated testing tools for verifying agent behavior without hitting live LLM APIs.

Key Exports

import { AgentTestRunner, MockModelProvider, ConversationSimulator } from '@kernova/core';
import type { AgentTestRunnerConfig } from '@kernova/core';

AgentTestRunner

Runs test scenarios against registered agents and asserts on results.

const runner = new AgentTestRunner(kernel, {
timeout: 10000,
verbose: true,
});
const result = await runner.run({
name: 'basic-query-test',
intent: { goal: 'What is 2+2?', intentType: 'query' },
assertions: [
(result) => result.success === true,
(result) => result.summary?.includes('4'),
],
});
console.log(`Test ${result.passed ? 'PASSED' : 'FAILED'}`);
// Run multiple scenarios
const results = await runner.runAll([scenario1, scenario2, scenario3]);
const passed = results.filter(r => r.passed).length;
console.log(`${passed}/${results.length} tests passed`);

MockModelProvider

A fake model provider that returns deterministic responses. Use in tests to avoid real API calls.

const mockProvider = new MockModelProvider({
defaultResponse: 'This is a mock response',
responses: {
'What is 2+2?': 'The answer is 4.',
'Hello': 'Hi there!',
},
});
const kernel = new KernovaKernel({
environment: 'development',
ephemeral: true,
providers: [mockProvider],
models: { default: { provider: 'mock', model: 'mock-model' } },
});

ConversationSimulator

Simulates multi-turn conversations for integration testing.

const simulator = new ConversationSimulator(kernel);
const result = await simulator.simulate([
{ role: 'user', content: 'Remember that my name is Alice' },
{ role: 'user', content: 'What is my name?' },
], { timeout: 30000 });
console.log(`Turns: ${result.turns.length}`);
result.turns.forEach(turn => {
console.log(` ${turn.role}: ${turn.content}`);
});

When to Use

  • Unit testing agent behavior
  • Integration testing without API costs
  • CI/CD pipelines for agent quality checks
  • Regression testing after agent changes

Configuration Reference

Full KernelConfig

import { KernovaKernel } from '@kernova/core';
import type { KernelConfig } from '@kernova/core';
const config: KernelConfig = {
// Instance identification
instanceId: 'my-app-prod-1',
// Environment (required)
environment: 'production',
// Debug logging
debug: false,
// Model routing
models: {
default: { provider: 'anthropic', model: 'claude-sonnet-5-5' },
// Per-purpose models: reasoning, generation, classification, extraction, conversation, vision, code, ...
overrides: {
code: { provider: 'anthropic', model: 'claude-sonnet-5-5' },
classification: { provider: 'openai', model: 'gpt-4o-mini' },
},
// Tried once when the default provider fails
fallback: { provider: 'openai', model: 'gpt-4o' },
},
// Additional providers (merged with auto-detected)
providers: [],
// Persistence directory
dataDir: '/var/lib/kernova',
// In-memory only (no SQLite)
ephemeral: false,
// Built-in tool configuration
builtInTools: {
enabled: ['http-fetch', 'file-read', 'file-write', 'date-time', 'web-search'],
disabled: ['shell-exec'], // Disable dangerous tools in production
sandboxDir: '/var/lib/kernova/workspace',
shellTimeout: 10000,
},
// Self-reflection
reflection: {
enabled: true,
threshold: 0.7,
maxAttempts: 2,
},
};
const kernel = new KernovaKernel(config);

ModelRoutingConfig

interface ModelRoutingConfig {
// Default model for all requests
default: {
provider: string; // e.g. 'openai', 'anthropic', 'gemini', 'ollama'
model: string; // e.g. 'gpt-4o', 'claude-sonnet-5-5'
};
// Purpose-specific overrides
purposes?: Record<string, {
provider: string;
model: string;
}>;
// Fallback chain (tried in order if primary fails)
fallback?: string[];
}

Environment Variables

Model providers are auto-detected from these environment variables:

VariableProvider
OPENAI_API_KEYOpenAI
ANTHROPIC_API_KEYAnthropic
GEMINI_API_KEYGoogle Gemini
DEEPSEEK_API_KEYDeepSeek
GROQ_API_KEYGroq
TOGETHER_API_KEYTogether AI
OPENROUTER_API_KEYOpenRouter
MISTRAL_API_KEYMistral
COHERE_API_KEYCohere
PERPLEXITY_API_KEYPerplexity
FIREWORKS_API_KEYFireworks AI
XAI_API_KEYxAI (Grok)
CEREBRAS_API_KEYCerebras
SAMBANOVA_API_KEYSambaNova

No configuration needed — if the key exists, the provider is available. Local servers (Ollama, LM Studio, vLLM, llama.cpp) need no key but aren’t detected: add them with providers: [createProvider('ollama', { baseUrl })].


Additional Modules

ModelFallbackManager

Automatic fallback when a provider fails. Tries providers in the configured fallback chain.

// Configured via models.fallback in KernelConfig
// Automatic — no direct interaction needed
// Access: kernel.fallback

TrajectoryRecorder

Records step-by-step execution traces for debugging. Enabled automatically when debug: true.

// Access traces for debugging (most recent first)
const traces = kernel.trajectory.listTraces();
traces.forEach(trace => {
console.log(`Intent: ${trace.metadata.intentGoal}, Steps: ${trace.events.length}`);
});

RateLimiter

Token-bucket rate limiter applied per identity. Configured via BudgetConfig.requestsPerMinute.

import { RateLimiter } from '@kernova/core';
// Usually accessed indirectly through budget enforcement
// Direct access: kernel.rateLimiter

ContextEngineManager

Pluggable context assembly. Register custom context engines that determine what information is assembled for each agent invocation.

import { ContextEngineManager, DefaultContextEngine } from '@kernova/core';
import type { ContextEnginePlugin } from '@kernova/core';

ToolAvailabilityEngine & ToolPolicyEngine

Control which tools are visible and allowed for each agent execution.

// ToolAvailabilityEngine — declarative visibility rules
// ToolPolicyEngine — layered allow/deny policies
// Both applied automatically during intent execution

HotReloader

Watches files for changes and reloads agent configs at runtime.

import { HotReloader } from '@kernova/core';
import type { HotReloaderConfig } from '@kernova/core';
// Used internally by DaemonRunner when watch: true

SecurityAuditor

Runs security checks against the kernel configuration and reports issues.

import { SecurityAuditor } from '@kernova/core';
import type { AuditResult, AuditCheck, AuditSeverity } from '@kernova/core';

PluginMarketplace

Discover and install plugins from a registry.

import { PluginMarketplace } from '@kernova/core';
import type { MarketplaceConfig, PluginListing } from '@kernova/core';

Complete Example

A full example combining multiple modules:

import { KernovaKernel, defineAgent, DaemonRunner, now } from '@kernova/core';
// 1. Create the kernel
const kernel = new KernovaKernel({
environment: 'production',
dataDir: './kernova-data',
models: {
default: { provider: 'anthropic', model: 'claude-sonnet-5-5' },
fallback: { provider: 'openai', model: 'gpt-4o' },
},
builtInTools: {
disabled: ['shell-exec'],
sandboxDir: './workspace',
},
reflection: { enabled: true, threshold: 0.75 },
});
// 2. Define agents
const researcher = defineAgent({
name: 'researcher',
description: 'Researches topics and provides detailed summaries',
capabilities: [
{ id: 'research', name: 'Research', description: 'Deep research', confidence: 0.9 },
],
tools: [
{ toolId: 'web-search', name: 'web-search', purpose: 'Search the web', required: true },
{ toolId: 'http-fetch', name: 'http-fetch', purpose: 'Fetch web pages', required: false },
],
instructions: `You are an expert researcher. Search the web for accurate,
up-to-date information and provide comprehensive summaries with sources.`,
});
const writer = defineAgent({
name: 'writer',
description: 'Writes polished content based on research',
capabilities: [
{ id: 'writing', name: 'Writing', description: 'Content creation', confidence: 0.95 },
],
tools: [{ toolId: 'file-write', name: 'file-write', purpose: 'Save drafts', required: false }],
instructions: `You are a professional writer. Create engaging, well-structured
content based on the provided context and research.`,
reflection: { enabled: true, threshold: 0.8, maxAttempts: 3 },
});
// 3. Start the kernel and register agents
await kernel.start();
kernel.agentRegistry.register(researcher.definition, researcher.executor);
kernel.agentRegistry.register(writer.definition, writer.executor);
// 4. Ingest documents for RAG
await kernel.rag.ingest(
'Company style guide: Use active voice, keep paragraphs under 3 sentences...',
'style-guide.md',
{ category: 'guidelines' }
);
// 5. Set up a content workflow (steps run in order; each agent step gets its own goal)
kernel.workflows.define({
id: 'blog-post', type: 'workflow_definition', version: '1.0.0', owner: 'system', status: 'active',
createdAt: now(), updatedAt: now(), metadata: {},
name: 'Blog Post Pipeline',
description: 'Research trending topics, then draft a post',
steps: [
{ id: 'research', name: 'Research', type: 'agent', onFailure: 'stop',
config: { agentId: 'researcher', input: { goal: 'Research trending AI topics this week' } } },
{ id: 'write', name: 'Write', type: 'agent', onFailure: 'stop',
config: { agentId: 'writer', input: { goal: 'Draft a blog post on the top trending AI topic' } } },
],
});
// 6. Schedule weekly content
kernel.scheduler.register({
name: 'weekly-blog',
cronExpression: '0 10 * * 1', // Monday at 10am
target: { type: 'intent', goal: 'Run the blog-post workflow for trending AI topics' },
});
// 7. Set budget limits
kernel.budget.setGlobalBudget({ maxTokens: 500_000, maxCostUsd: 25.00 });
// 8. Subscribe to events for monitoring
kernel.events.subscribe(['intent.completed'], (event) => {
console.log(`✓ Completed: ${event.data.intentId}`);
});
kernel.events.subscribe(['intent.failed'], (event) => {
console.error(`✗ Failed: ${event.data.error}`);
});
// 9. Run as a daemon
const daemon = new DaemonRunner(kernel, {
watch: true,
configPath: './agents/',
heartbeatIntervalMs: 30000,
});
await daemon.start(); // Blocks until SIGINT/SIGTERM

Exports Summary

Everything exported from @kernova/core:

// Core
export { KernovaKernel, defineAgent };
export type { KernelConfig, AgentSpec, DefinedAgent };
// Events
export { EventBus, EventStore };
// Memory
export { MemoryEngine, MemoryStore };
// Models
export { ModelRouter, OpenAIProvider, AnthropicProvider, GeminiProvider, OllamaProvider, OpenAICompatibleProvider };
export { createProvider, detectAvailableProviders, listPresets, createProviderFromConfig };
// Agents
export { AgentRegistry, AgentCoordinator };
export type { AgentExecutor, AgentTools };
// Plugins
export { PluginRegistry };
export type { KernovaPlugin, ToolDefinition, MiddlewareHook };
// Workflows
export { WorkflowEngine };
// Intelligence
export { AgentPlanner, SelfReflection, ConversationManager, RAGPipeline };
// Autonomy
export { Scheduler, TaskQueue, ProactiveTriggerEngine, BackgroundLoopModule };
// Channels
export { ConnectorRegistry, WebhookChannelAdapter, WebSocketChannelAdapter };
// Infrastructure
export { DaemonRunner, AgentGateway, MCPBridge };
export { MetricsCollector, HealthMonitor, SandboxManager };
export { IdentityManager, ApiKeyManager, PermissionEngine, SessionManager };
export { BudgetManager, RateLimiter };
// Testing
export { AgentTestRunner, MockModelProvider, ConversationSimulator };
// Built-in Tools
export { BuiltInToolRegistry, SandboxViolationError };
// Utilities
export { generateId, now, ValidationError, QueueFullError, ConnectorError };