/** * OpenKernel — Core Type Definitions * * Provider-agnostic AI execution kernel types. * Mission → Objectives → Tasks → Workers → Providers. */ export type Capability = 'coding' | 'browser' | 'vision' | 'terminal' | 'planning' | 'reasoning' | 'filesystem' | 'search' | 'crawl' | 'ocr' | 'review' | 'summarize' | 'citations' | 'translation' | 'documentation' | 'architecture' | 'verification' | 'frontend' | 'design' | 'accessibility' | 'dataviz' | 'animation' | (string & {}); export type WorkerType = 'research' | 'browser' | 'coding' | 'architecture' | 'vision' | 'review' | 'documentation' | 'translation' | 'terminal' | 'verification' | 'frontend' | (string & {}); export type MissionStatus = 'NEW' | 'PLANNING' | 'READY' | 'RUNNING' | 'VERIFYING' | 'WAITING' | 'PAUSED' | 'FAILED' | 'COMPLETED' | 'CANCELLED'; export type TaskStatus = 'PENDING' | 'QUEUED' | 'RUNNING' | 'VERIFYING' | 'COMPLETED' | 'FAILED' | 'SKIPPED'; export type WorkerStatus = 'SPAWNED' | 'INITIALIZED' | 'EXECUTING' | 'VERIFYING' | 'COMPLETED' | 'FAILED' | 'DESTROYED'; export interface Objective { id: string; missionId: string; description: string; capabilities: Capability[]; acceptanceCriteria: string[]; taskIds: string[]; status: TaskStatus; createdAt: number; completedAt?: number; /** Human phase label for large projects (e.g. "architecture", "frontend"). */ phase?: string; /** * Minimum model benchmark (0–100) this phase should route to. Lets the * orchestrator assign a more capable model to demanding phases (architecture, * verification) and a cheaper one to light phases (docs) — instead of one * model for the whole mission. Flows into each task's routing floor. */ minBenchmark?: number; } export interface Task { id: string; objectiveId: string; missionId: string; description: string; capabilities: Capability[]; dependencies: string[]; status: TaskStatus; assignedWorkerId?: string; providerId?: string; modelId?: string; input: TaskInput; output?: TaskOutput; attempts: number; maxAttempts: number; createdAt: number; startedAt?: number; completedAt?: number; error?: string; /** Routing floor for this task/phase (0–100). Escalates upward on repeated * verification failure so the task climbs to a more capable model. */ minBenchmark?: number; /** How many times this task's output failed verification — drives model escalation. */ verificationFailures?: number; } export interface TaskInput { prompt: string; context?: Record; files?: string[]; artifacts?: Artifact[]; } export interface TaskOutput { content: string; artifacts?: Artifact[]; metrics?: TaskMetrics; providerId?: string; modelId?: string; tokensIn?: number; tokensOut?: number; durationMs?: number; } export interface Artifact { id: string; type: 'file' | 'code' | 'document' | 'url' | 'data' | 'image'; path?: string; content?: string; mimeType?: string; metadata?: Record; } export interface TaskMetrics { durationMs: number; tokensIn: number; tokensOut: number; cost?: number; retries: number; } export interface Mission { id: string; name: string; description: string; goal: string; status: MissionStatus; objectives: Objective[]; tasks: Task[]; policy: PolicyRef; workspace: WorkspaceRef; checkpoints: string[]; currentObjectiveId?: string; currentTaskId?: string; createdAt: number; startedAt?: number; completedAt?: number; error?: string; metadata?: Record; } export interface WorkspaceRef { root: string; git?: { branch?: string; commit?: string; dirty?: boolean; }; } export interface WorkerDefinition { type: WorkerType; capabilities: Capability[]; preferences: WorkerPreferences; verification?: string; } export interface WorkerPreferences { reasoning?: number; speed?: number; cost?: 'free' | 'low' | 'medium' | 'high'; contextLength?: number; vision?: boolean; } export interface WorkerInstance { id: string; type: WorkerType; capabilities: Capability[]; preferences: WorkerPreferences; status: WorkerStatus; missionId: string; taskId?: string; providerId?: string; modelId?: string; createdAt: number; startedAt?: number; completedAt?: number; result?: TaskOutput; error?: string; } export interface ProviderModel { id: string; name: string; providerId: string; contextLength: number; capabilities: Capability[]; supportsStreaming: boolean; supportsFunctionCalling: boolean; supportsVision: boolean; /** * Reasoning/quality benchmark score (0–100). Spec input "Benchmark Scores". * When absent, the router estimates it from parameter size / model family. */ benchmarkScore?: number; /** * Max tokens accepted in a single request given the provider tier's rate * limits (e.g. Groq free ≈ 12k TPM), which can be far below `contextLength`. * Defaults to `contextLength` when unknown. Used by the router to avoid * "request too large" errors on rate-limited free tiers. */ maxRequestTokens?: number; costPer1kTokens?: { input?: number; output?: number; }; metadata?: Record; } export interface ProviderInfo { id: string; name: string; type: 'local' | 'cloud'; healthy: boolean; baseURL?: string; available: boolean; lastCheckedAt?: number; latencyMs?: number; successRate?: number; quotaRemaining?: number; /** * Provider-tier per-minute token limit (from rate-limit headers), applied to * ALL of this provider's models unless a model overrides it. e.g. Groq free * ≈ 12k, HF ≈ 400k. Used by the router to size requests. */ maxRequestTokens?: number; error?: string; /** * When set and in the future, the provider is on a recovery cooldown (out of * credits, bad key, rate-limited, or down) and is excluded from routing until * this time. Prevents a broke/dead provider — whose /models still responds — * from being resurrected by the health check and re-picked every task. */ cooldownUntil?: number; } export interface ProviderCapabilities { streaming: boolean; functionCalling: boolean; vision: boolean; maxContextLength: number; models: ProviderModel[]; } export interface CompletionRequest { model: string; prompt: string; systemPrompt?: string; context?: Record; maxTokens?: number; temperature?: number; stream?: boolean; tools?: ToolDefinition[]; artifacts?: Artifact[]; } export interface CompletionChunk { delta: string; done: boolean; providerId: string; modelId: string; tokensIn?: number; tokensOut?: number; } export interface CompletionResult { content: string; providerId: string; modelId: string; tokensIn: number; tokensOut: number; durationMs: number; cost?: number; toolCalls?: ToolCall[]; artifacts?: Artifact[]; } export interface ToolDefinition { name: string; description: string; parameters: Record; } export interface ToolCall { name: string; arguments: Record; } export type PolicyName = 'free-first' | 'fastest' | 'highest-quality' | 'local-first' | 'privacy-first' | 'balanced' | 'offline' | (string & {}); export interface Policy { name: PolicyName; execution?: { parallelism?: number; timeout?: number; }; routing?: { mode?: 'free-first' | 'fastest' | 'quality' | 'local' | 'privacy' | 'balanced' | 'offline'; preferredProviders?: string[]; blockedProviders?: string[]; }; verification?: { strict?: boolean; levels?: string[]; }; checkpoint?: { everyTask?: boolean; intervalSeconds?: number; }; retry?: { maxAttempts?: number; backoffMs?: number; }; notifications?: { channels?: string[]; }; } export interface PolicyRef { name: PolicyName; policy: Policy; } export interface Checkpoint { id: string; missionId: string; mission: Mission; workerStates: WorkerInstanceState[]; timestamp: number; reason: 'task' | 'interval' | 'pause' | 'crash' | 'manual'; /** Recent event log for this mission — restored so long-running/crash recovery * keeps its activity trail. */ logs?: KernelEvent[]; /** Free-form memory bag persisted with the checkpoint (mission.metadata plus * any harness-supplied working memory). */ memory?: Record; } export interface WorkerInstanceState { workerId: string; status: WorkerStatus; taskId?: string; providerId?: string; modelId?: string; partialOutput?: string; } export type KernelEventType = 'MISSION_STARTED' | 'MISSION_COMPLETED' | 'MISSION_FAILED' | 'MISSION_PAUSED' | 'MISSION_RESUMED' | 'MISSION_CANCELLED' | 'PLAN_CREATED' | 'OBJECTIVE_STARTED' | 'OBJECTIVE_COMPLETED' | 'TASK_QUEUED' | 'TASK_STARTED' | 'TASK_COMPLETED' | 'TASK_FAILED' | 'WORKER_SPAWNED' | 'WORKER_EXITED' | 'ROUTING_DECISION' | 'MODEL_CHANGED' | 'PROVIDER_CHANGED' | 'CHECKPOINT' | 'VERIFY_SUCCESS' | 'VERIFY_FAILED' | 'RECOVERY' | 'PROVIDER_HEALTH' | 'NOTIFICATION' | 'LOG'; export interface KernelEvent { type: KernelEventType; timestamp: number; missionId?: string; objectiveId?: string; taskId?: string; workerId?: string; data?: T; } export type EventHandler = (event: KernelEvent) => void | Promise; export interface RoutingRequest { capabilities: Capability[]; preferences: WorkerPreferences; policy: Policy; availableProviders: ProviderInfo[]; availableModels: ProviderModel[]; /** * Estimated tokens in the request (prompt + context). When set, the router * heavily penalizes models whose effective per-request limit is below it, * preventing "request too large" failures on rate-limited tiers. */ estimatedRequestTokens?: number; /** * Minimum acceptable model benchmark (0–100). Models below the floor are * heavily penalized (not hard-excluded), so demanding phases route to capable * models and escalation can climb the tier ladder. */ minBenchmark?: number; } export interface RoutingDecision { providerId: string; modelId: string; score: number; reason: string; } /** A single scored routing option, used to render the orchestrator's choice. */ export interface RoutingCandidate extends RoutingDecision { providerName: string; providerType: 'local' | 'cloud'; benchmarkScore: number; } /** Payload of the ROUTING_DECISION event — the ranked candidates + the winner. */ export interface RoutingDecisionEvent { taskId: string; workerType: string; mode: string; /** True when the choice was forced (worker pin, recovery override, or offline lock). */ locked: boolean; chosen: RoutingCandidate; candidates: RoutingCandidate[]; } export interface VerificationResult { passed: boolean; checks: VerificationCheck[]; score: number; summary: string; } export interface VerificationCheck { name: string; passed: boolean; message: string; durationMs?: number; } export type VerificationStage = 'objective' | 'compile' | 'tests' | 'lint' | 'browser' | 'expected-output' | 'quality' | 'llm-judge'; /** * Frontend "worker request" acceptance criteria — the quality bar a frontend * task must clear. Travels in `task.input.context.frontendAcceptance` and is * enforced by the frontend-quality verifier. Any omitted field uses a default. */ export interface FrontendAcceptance { /** Pass threshold, 0–100 (default 85). */ threshold?: number; /** Minimum distinct CSS class selectors (component proxy). */ minComponents?: number; /** Minimum distinct theme selectors ([data-theme=…] / .theme-…). */ minThemes?: number; /** Minimum distinct design-token custom properties (--token). */ minTokens?: number; /** Frameworks that must NOT appear (hard gate). */ bannedFrameworks?: string[]; /** Require design tokens / responsive / animation / a11y sections. */ requireDesignTokens?: boolean; requireResponsive?: boolean; requireAnimation?: boolean; requireAccessibility?: boolean; /** Fail if placeholder/TODO/lorem content is present (hard gate). */ noPlaceholders?: boolean; } /** One line item of a frontend quality score. */ export interface FrontendScoreItem { name: string; weight: number; earned: number; detail: string; } export interface FrontendScore { score: number; passed: boolean; threshold: number; items: FrontendScoreItem[]; /** Actionable notes for the next attempt when the bar isn't met. */ feedback: string[]; } export interface VerificationContext { mission: Mission; task: Task; output: TaskOutput; strict: boolean; workspace: WorkspaceRef; } export interface Verifier { stage: VerificationStage; enabled(ctx: VerificationContext): boolean; run(ctx: VerificationContext): Promise; } export interface LlmJudgeOptions { providerId?: string; modelId?: string; } export type FailureType = '429' | 'timeout' | 'provider-down' | 'quota-exhausted' | 'auth-failure' | 'context-overflow' | 'content-filter' | 'hallucination' | 'tool-failure' | 'verification-failure' | 'planning-failure' | 'browser-failure' | 'unknown'; export type RecoveryAction = 'retry' | 'rotate-provider' | 'escalate-model' | 'spawn-different-worker' | 'replan' | 'checkpoint' | 'continue' /** Park the task and retry after a backoff — for transient exhaustion (rate * limit / all providers cooling down) where the work must NOT be abandoned. */ | 'wait-retry' | 'abort'; export interface RecoveryDecision { action: RecoveryAction; reason: string; rotateToProviderId?: string; rotateToModelId?: string; newWorkerType?: WorkerType; /** For 'escalate-model': the benchmark of the more-capable target, so the * orchestrator can raise the task's routing floor and keep climbing. */ escalateToBenchmark?: number; } export interface PluginManifest { name: string; version: string; description?: string; subscriptions?: KernelEventType[]; commands?: PluginCommand[]; } export interface PluginCommand { name: string; description: string; handler: (args: string[], kernel: KernelLike) => Promise; } export interface Plugin { manifest: PluginManifest; onEvent?(event: KernelEvent): void | Promise; onRegister?(kernel: KernelLike): void | Promise; onDestroy?(): void | Promise; } export interface KernelLike { execute(mission: MissionInput): Promise; pause(missionId: string): Promise; resume(missionId: string): Promise; cancel(missionId: string): Promise; retry(missionId: string): Promise; status(missionId: string): Promise; subscribe(types: KernelEventType[], handler: EventHandler): () => void; subscribeAll(handler: EventHandler): () => void; registerWorker(definition: WorkerDefinition): void; registerProvider(providerId: string, provider: ProviderInterface): void; registerPlugin(plugin: Plugin): void; registerPolicy(policy: Policy): void; getMission(missionId: string): Mission | undefined; listMissions(): Mission[]; listPlugins(): Plugin[]; getEventHistory(): KernelEvent[]; notify(message: string, missionId?: string): void; /** Run an OpenKernel slash-command (e.g. "/status", "/goal build X"). */ command(input: string): Promise; } /** Result of running a kernel command — a renderable text plus optional data. */ export interface CommandResult { ok: boolean; text: string; data?: unknown; } export interface MissionInput { name?: string; description: string; goal: string; policy?: PolicyName; workspace?: WorkspaceRef; tasks?: MissionTaskInput[]; /** * Explicit phase breakdown (each phase → one objective). When present it wins * over `tasks`. Harnesses (e.g. InfiniBot) can pass phases directly with * capabilities written naturally ("backend", "ui", "tests") — they're * normalized to canonical capabilities and each phase routes to its own model * tier via its benchmark floor. */ phases?: MissionPhaseInput[]; /** * When true and neither `tasks` nor `phases` is given, the MissionPlanner * decomposes `goal` into phases (LLM-driven, heuristic fallback) before * execution — turning a one-line goal into architecture → implementation → * verification phases, each with an appropriate model. */ autoPlan?: boolean; metadata?: Record; } export interface MissionTaskInput { description: string; capabilities: Capability[]; dependencies?: string[]; input: TaskInput; } /** * A phase of a mission — becomes one Objective plus its tasks. Capabilities may * be written naturally (natural language / synonyms) and are normalized; the * phase's model tier is derived from them unless `minBenchmark` is set. */ export interface MissionPhaseInput { /** Short phase label, e.g. "architecture", "backend", "frontend", "tests". */ name: string; description: string; /** Needed capabilities — natural names allowed ("backend", "ui", "testing"). */ capabilities?: string[]; acceptanceCriteria?: string[]; /** Names of phases that must finish before this one starts. */ dependsOn?: string[]; /** Explicit tasks; if omitted the phase runs as a single task from its description. */ tasks?: MissionTaskInput[]; /** Explicit model benchmark floor (0–100); else derived from capabilities. */ minBenchmark?: number; } export interface ProviderVerifyResult { ok: boolean; latencyMs: number; error?: string; /** Per-minute token limit parsed from rate-limit headers, if provided. */ rateLimitTokens?: number; } export interface ProviderInterface { info: ProviderInfo; capabilities(): Promise; complete(request: CompletionRequest): Promise; completeStream?(request: CompletionRequest): AsyncIterable; refresh?(): Promise; /** * Actively verify the provider with a real, token-authenticated 1-token * completion — proves reachability, a valid key, and a working chat/model. * Preferred by the health check over a plain /models probe. */ verify?(): Promise; } export type LogLevel = 'debug' | 'info' | 'warn' | 'error'; export interface Logger { debug(message: string, ...args: unknown[]): void; info(message: string, ...args: unknown[]): void; warn(message: string, ...args: unknown[]): void; error(message: string, ...args: unknown[]): void; }