import { ZodError, z, ZodType, ZodSafeParseResult } from 'zod'; import { C as CliNameLiteral, a as CliName, b as CliTransport, c as CliResponse, d as CliError, H as HealthStatus, e as CapacityStatus, T as TokenUsage$1, O as ObservedArmId, I as InputModality, f as OutputModality, g as ToolCapability, S as SpecialFeature, P as Pricing, Q as QualityScores, R as RoutingArmId, M as ModelId, V as VersionStatus, E as EndpointArmId, D as DispatchEnum, h as ConsensusAlgorithm, i as Vote, j as VoteDecision$1, k as ProposalStatus, l as RejectedModeKey, m as VoterRole, A as AgentVoteResult, n as ResolvedVoterProject, o as DecisionCostSummary, p as CliErrorCode, q as VoteCounts, W as WeightedVoteCounts, r as WeightBasis, s as AgentPerformance, t as ProposalState, u as ProposalId, v as ConsensusEngineConfig, w as ConsensusResult, x as Proposal, y as ConsensusMetrics, z as VoterExpansionCallback, B as VotingStrategy, F as ErrorPolicy } from './consensus-vote-types-DkRs8FbB.js'; export { G as AgentPerformanceSchema, J as AgentVoteSummary, K as ConsensusAlgorithmSchema, L as ConsensusEngineConfigSchema, N as ConsensusMetricsSchema, U as ConsensusResultSchema, X as ConsensusVoteInput, Y as ConsensusVoteInputSchema, Z as ConsensusVoteResponse, _ as DEFAULT_CONSENSUS_CONFIG, $ as ProposalSchema, a0 as ProposalStatusSchema, a1 as REJECTION_CATEGORIES, a2 as RejectionCategory, a3 as RejectionCategorySchema, a4 as VoteDecisionStatus, a5 as VoteSchema } from './consensus-vote-types-DkRs8FbB.js'; import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; import { Transport } from '@modelcontextprotocol/sdk/shared/transport.js'; /** * nexus-agents - Version constant * * Injected at build time via tsup define from package.json. * Do NOT edit VERSION manually — it is replaced during build. */ declare const VERSION: string; /** * nexus-agents/core - Result Pattern * * Type-safe Result pattern for handling fallible operations without exceptions. * Inspired by Rust's Result type. */ /** * A discriminated union representing either success (Ok) or failure (Err). * @template T - The success value type * @template E - The error value type */ type Result = { readonly ok: true; readonly value: T; } | { readonly ok: false; readonly error: E; }; /** * Creates a successful Result containing the given value. * @template T - The success value type * @param value - The success value * @returns A Result in the Ok state * * @example * ```typescript * const result = ok(42); * if (result.ok) { * console.log(result.value); // 42 * } * ``` */ declare function ok(value: T): Result; /** * Creates a failed Result containing the given error. * @template E - The error value type * @param error - The error value * @returns A Result in the Err state * * @example * ```typescript * const result = err(new Error('not found')); * if (!result.ok) { * console.error(result.error.message); // "not found" * } * ``` */ declare function err(error: E): Result; /** * Type guard to check if a Result is in the Ok state. * @template T - The success value type * @template E - The error value type * @param result - The Result to check * @returns True if the Result is Ok */ declare function isOk(result: Result): result is { readonly ok: true; readonly value: T; }; /** * Type guard to check if a Result is in the Err state. * @template T - The success value type * @template E - The error value type * @param result - The Result to check * @returns True if the Result is Err */ declare function isErr(result: Result): result is { readonly ok: false; readonly error: E; }; /** * Transforms the success value of a Result using the provided function. * @template T - The original success value type * @template U - The transformed success value type * @template E - The error value type * @param result - The Result to transform * @param fn - The transformation function * @returns A new Result with the transformed value */ declare function map(result: Result, fn: (value: T) => U): Result; /** * Transforms the error value of a Result using the provided function. * @template T - The success value type * @template E - The original error value type * @template F - The transformed error value type * @param result - The Result to transform * @param fn - The transformation function * @returns A new Result with the transformed error */ declare function mapErr(result: Result, fn: (error: E) => F): Result; /** * Extracts the success value from a Result. * @template T - The success value type * @template E - The error value type * @param result - The Result to unwrap * @returns The success value * @throws Throws an Error wrapping the error value if the Result is Err */ declare function unwrap(result: Result): T; /** * Extracts the success value from a Result, or returns a default value. * @template T - The success value type * @template E - The error value type * @param result - The Result to unwrap * @param defaultValue - The default value to return if Err * @returns The success value or the default value * * @example * ```typescript * const result = err(new Error('failed')); * const value = unwrapOr(result, 'fallback'); * console.log(value); // "fallback" * ``` */ declare function unwrapOr(result: Result, defaultValue: T): T; /** * nexus-agents/core - Error Hierarchy * * Structured error classes for consistent error handling across the codebase. */ /** * Error codes for all Nexus Agents errors. */ declare const ErrorCode: { readonly VALIDATION_ERROR: "VALIDATION_ERROR"; readonly INVALID_INPUT: "INVALID_INPUT"; readonly MISSING_REQUIRED: "MISSING_REQUIRED"; readonly SCHEMA_ERROR: "SCHEMA_ERROR"; readonly CONFIG_ERROR: "CONFIG_ERROR"; readonly CONFIG_NOT_FOUND: "CONFIG_NOT_FOUND"; readonly CONFIG_INVALID: "CONFIG_INVALID"; readonly MODEL_ERROR: "MODEL_ERROR"; readonly MODEL_UNAVAILABLE: "MODEL_UNAVAILABLE"; /** * Model is reachable but the requested id no longer exists — typically a * 404 from /v1/chat/completions, an Anthropic `model_not_found` error, * or a vendor "this model has been deprecated" message. Distinct from * MODEL_UNAVAILABLE (transient 502/503 service overload) — this one * means the model is gone, retry won't help, route to a different id. * Surfaced to the caller as-is: automatic substitution was removed in * #4408 because answering with a model the caller did not request * records the substitute's outcome under the requested model's id. */ readonly MODEL_NOT_FOUND: "MODEL_NOT_FOUND"; readonly MODEL_RATE_LIMITED: "MODEL_RATE_LIMITED"; readonly MODEL_TIMEOUT: "MODEL_TIMEOUT"; /** * The model rejected a request parameter by name — a 400 that identifies an * unsupported `param` (e.g. a post-Opus-4.6 Claude or an OpenAI reasoning model * 400-ing on `temperature`). NON-RETRYABLE: retrying an identical request with * the same bad param will 400 again. The offending param name is carried in the * error `context.param`. Distinct from generic MODEL_ERROR so callers/telemetry * (#4069) and the reactive self-heal path (#4071) can act on the named param. */ readonly MODEL_PARAMETER_UNSUPPORTED: "MODEL_PARAMETER_UNSUPPORTED"; readonly AGENT_ERROR: "AGENT_ERROR"; readonly AGENT_NOT_FOUND: "AGENT_NOT_FOUND"; readonly AGENT_EXECUTION_FAILED: "AGENT_EXECUTION_FAILED"; readonly AGENT_MEMORY_FAILURE: "AGENT_MEMORY_FAILURE"; readonly AGENT_REFLECTION_FAILURE: "AGENT_REFLECTION_FAILURE"; readonly AGENT_PLANNING_FAILURE: "AGENT_PLANNING_FAILURE"; readonly AGENT_ACTION_FAILURE: "AGENT_ACTION_FAILURE"; readonly WORKFLOW_ERROR: "WORKFLOW_ERROR"; readonly WORKFLOW_NOT_FOUND: "WORKFLOW_NOT_FOUND"; readonly WORKFLOW_PARSE_ERROR: "WORKFLOW_PARSE_ERROR"; readonly WORKFLOW_EXECUTION_FAILED: "WORKFLOW_EXECUTION_FAILED"; readonly SECURITY_ERROR: "SECURITY_ERROR"; readonly PATH_TRAVERSAL: "PATH_TRAVERSAL"; readonly UNAUTHORIZED: "UNAUTHORIZED"; readonly TIMEOUT_ERROR: "TIMEOUT_ERROR"; readonly RATE_LIMIT_ERROR: "RATE_LIMIT_ERROR"; readonly INTERNAL_ERROR: "INTERNAL_ERROR"; }; type ErrorCode = (typeof ErrorCode)[keyof typeof ErrorCode]; /** * Serialized error format for JSON output. */ interface SerializedError { name: string; code: ErrorCode; message: string; context?: Record; cause?: SerializedError; stack?: string; } /** * Options for creating a NexusError. */ interface NexusErrorOptions { code: ErrorCode; cause?: Error; context?: Record; } /** * Base error class for all Nexus Agents errors. */ declare class NexusError extends Error { readonly code: ErrorCode; readonly context: Record | undefined; readonly cause: Error | undefined; constructor(message: string, options: NexusErrorOptions); /** * Serializes the error to a JSON-safe object. */ toJSON(): SerializedError; } /** * Validation error for invalid inputs or schema violations. */ declare class ValidationError$1 extends NexusError { constructor(message: string, options?: Partial>); } /** * Configuration error for missing or invalid configuration. */ declare class ConfigError extends NexusError { constructor(message: string, options?: Partial>); } /** * Model error for model adapter failures. * * Subclasses (e.g., AdapterModelError) can pass a specific ErrorCode * to categorize failures more granularly (rate-limited, timeout, etc.). */ declare class ModelError extends NexusError { constructor(message: string, options?: Partial); } /** * Agent error for agent execution failures. */ declare class AgentError$1 extends NexusError { constructor(message: string, options?: Partial>); } /** * Workflow error for workflow parsing or execution failures. */ declare class WorkflowError extends NexusError { constructor(message: string, options?: Partial>); } /** * Security error for security violations. */ declare class SecurityError extends NexusError { constructor(message: string, options?: Partial>); } /** * Timeout error for operation timeouts. */ declare class TimeoutError extends NexusError { constructor(message: string, options?: Partial>); } /** * Options for creating a rate limit error with actionable context. * (Source: Issue #996 — Rate limit error surfacing) */ interface RateLimitErrorOptions extends Partial> { /** Milliseconds until the rate limit window resets. */ readonly retryAfterMs?: number; /** ISO timestamp when the rate limit window resets. */ readonly windowResetAt?: string; /** Provider or adapter that was rate-limited. */ readonly provider?: string; } /** * Rate limit error with actionable backoff context. * (Source: Issue #996 — Rate limit error surfacing) */ declare class RateLimitError extends NexusError { readonly retryAfterMs: number | undefined; readonly windowResetAt: string | undefined; readonly provider: string | undefined; constructor(message: string, options?: RateLimitErrorOptions); } /** * nexus-agents/core - Structured Logger * * JSON-structured logging with secret sanitization. */ /** Log levels in order of severity */ type LogLevel = 'debug' | 'info' | 'warn' | 'error'; /** Log output format */ type LogFormat = 'json' | 'pretty'; /** Log output destination */ type LogDestination = 'stdout' | 'stderr' | 'file'; /** Log context/metadata */ interface LogContext { [key: string]: unknown; } /** Structured log entry */ interface LogEntry { timestamp: string; level: LogLevel; message: string; context?: LogContext; error?: { name: string; message: string; stack?: string; }; } /** Logger interface */ interface ILogger { debug(message: string, context?: LogContext): void; info(message: string, context?: LogContext): void; warn(message: string, context?: LogContext): void; error(message: string, error?: Error, context?: LogContext): void; child(context: LogContext): ILogger; setLevel(level: LogLevel): void; /** Set output format (json or pretty) - optional for backward compatibility */ setFormat?: ((format: LogFormat) => void) | undefined; /** Set output destination (stdout, stderr, or file) - optional for backward compatibility */ setDestination?: ((destination: LogDestination, filePath?: string) => void) | undefined; } /** * Sanitizes a string by redacting known secret patterns. */ declare function sanitize(text: string): string; /** * Creates a structured logger with configurable format and destination. * (Source: Issue #485 - Wire logging.format and logging.destination) */ declare function createLogger(baseContext?: LogContext): ILogger; /** Default logger instance */ declare const logger: ILogger; /** * nexus-agents/core - Zod Validation Helpers * * Centralized utilities for Zod error formatting. * Consolidates 20+ duplicate implementations across the codebase. * * @module core/zod-helpers * (Source: LOOP H-K consolidation) */ /** * Type guard to check if a value is a Zod error. * * @param error - The value to check * @returns True if the value is a ZodError * * @example * ```typescript * if (isZodError(error)) { * console.error(formatZodError(error)); * } * ``` */ declare function isZodError(error: unknown): error is ZodError; /** * nexus-agents/core - Agent Types * * Base interface for all agents (TechLead, Experts, dynamic agents). */ /** * Agent state in the lifecycle. */ type AgentState$2 = 'idle' | 'thinking' | 'acting' | 'waiting' | 'error'; /** * Predefined agent roles. */ type AgentRole = 'orchestrator' | 'code_expert' | 'architecture_expert' | 'security_expert' | 'documentation_expert' | 'testing_expert' | 'devops_expert' | 'research_expert' | 'pm_expert' | 'ux_expert' | 'infrastructure_expert' | 'qa_expert' | 'data_visualization_expert' | 'thinker' | 'worker' | 'verifier' | 'custom'; /** * Agent capabilities. */ declare const AgentCapability: { readonly TASK_EXECUTION: "task_execution"; readonly DELEGATION: "delegation"; readonly COLLABORATION: "collaboration"; readonly TOOL_USE: "tool_use"; readonly CODE_GENERATION: "code_generation"; readonly CODE_REVIEW: "code_review"; readonly RESEARCH: "research"; }; type AgentCapability = (typeof AgentCapability)[keyof typeof AgentCapability]; /** * Task context and constraints. */ interface TaskContext { /** Working directory or scope */ workingDirectory?: string; /** Relevant files */ files?: string[]; /** Previous messages in conversation */ history?: TaskHistoryItem[]; /** Additional metadata */ metadata?: Record; } interface TaskHistoryItem { role: 'user' | 'assistant' | 'system'; content: string; timestamp: string; } /** * Constraints on task execution. * * @remarks * Enforcement status of each field (Issue #469): * - `maxDuration`: ENFORCED - Task times out after this duration * - `maxTokens`: INFORMATIONAL - Included in task context for agent awareness, not enforced * - `outputFormat`: DEPRECATED - Not enforced, will be removed in v3.0 * - `allowedTools`: DEPRECATED - Not enforced, will be removed in v3.0 */ interface TaskConstraints$1 { /** Maximum execution time in ms. ENFORCED via timeout mechanism. */ maxDuration?: number; /** * Maximum tokens to use. INFORMATIONAL only - agents can see this but it's not enforced. * Use model adapter budgets for actual token enforcement. */ maxTokens?: number; } /** * Task to be executed by an agent. */ interface Task$1 { /** Unique task identifier */ id: string; /** Task description */ description: string; /** Task context */ context: TaskContext; /** Optional constraints. See {@link TaskConstraints} for enforcement status. */ constraints?: TaskConstraints$1; /** * Priority (higher = more urgent). * INFORMATIONAL - Logged but not used for scheduling or execution order. */ priority?: number; } /** * Metadata about task execution. */ interface ResultMetadata { /** Execution duration in ms */ durationMs: number; /** Tokens used. Meaningful only when {@link ResultMetadata.tokensMeasured} is not `false`. */ tokensUsed: number; /** * Whether `tokensUsed` is a measurement (#4734). * * `false` means the adapter reported no usage, so `tokensUsed` is a * placeholder zero and NOT a count — a step that consumed unreported tokens * must not be read as having spent nothing, which for a spend cap * under-counts in the dangerous direction. * * Absent means the producer predates this distinction: unknown, not * measured. `step-executor` only drops a value on an explicit `false`, so a * legacy producer keeps its current behaviour. * * This flag exists because `tokensUsed` is required on a structurally public * type (`TaskResult.metadata`, exported via `exports/core.ts:52`), so making * it optional would break every downstream reader. The workflow ledger reads * `StepResult.tokensUsed`, which is already optional and CAN represent * absence — see #4744. */ tokensMeasured?: boolean; /** Tools invoked */ toolsUsed: string[]; /** Model used */ model: string; /** CLI used by the last model-backed step, when the adapter reports CLI identity. */ readonly executedCli?: CliNameLiteral; /** Whether the executed CLI identity was measured or remains unknown. */ readonly executedCliSource?: 'executed' | 'unknown'; } /** * Result of task execution. */ interface TaskResult { /** Task that was executed */ taskId: string; /** Result output */ output: unknown; /** Execution metadata */ metadata: ResultMetadata; } /** * Inter-agent message types. */ type AgentMessageType = 'task' | 'result' | 'query' | 'feedback' | 'status'; /** * Message between agents. */ interface AgentMessage { /** Unique message identifier */ id: string; /** Sender agent ID */ from: string; /** Recipient agent ID */ to: string; /** Message type */ type: AgentMessageType; /** Message payload */ payload: unknown; /** Timestamp */ timestamp: string; } /** * Response to an agent message. */ interface AgentResponse { /** Original message ID */ messageId: string; /** Response status */ status: 'accepted' | 'rejected' | 'completed' | 'failed'; /** Response data */ data?: unknown; /** Error message if failed */ error?: string; } /** * Context provided during agent initialization. */ interface AgentContext { /** Agent configuration */ config: AgentConfig; /** Available tools */ tools?: string[]; /** Shared memory/state */ sharedState?: Record; } /** * Agent configuration. */ interface AgentConfig { /** Model to use */ modelId: string; /** Temperature for generation */ temperature?: number; /** System prompt */ systemPrompt?: string; /** Maximum context tokens */ maxContextTokens?: number; } /** * Base interface for all agents. */ interface IAgent { /** Unique agent identifier */ readonly id: string; /** Agent role */ readonly role: AgentRole; /** Current state */ readonly state: AgentState$2; /** Agent capabilities */ readonly capabilities: readonly AgentCapability[]; /** * Execute a task. * @param task - Task to execute * @param options - Optional execution options (#3016/#3040). * `signal` cancels the in-flight model call when the caller's deadline * wins a race; without it, the SDK keeps running to its own 10-minute * timeout after the caller has already discarded the result. * @returns Result with TaskResult or AgentError */ execute(task: Task$1, options?: { signal?: AbortSignal; }): Promise>; /** * Handle an inter-agent message and return a response. * * **Delivery semantics (#3222).** This is a *direct, awaited request/response* * call: the caller invokes it and holds the returned promise. It is NOT a * queued or broadcast channel — that is the collaboration event bus * (`agents/collaboration/event-bus.ts`), a fire-and-forget pub/sub with its * own semantics. For this method specifically: * - **Ordering** is the caller's responsibility. Sequential `await`s are * handled in call order; concurrent calls carry no cross-message ordering * guarantee. * - **Delivery** is exactly the method invocation — there is **no automatic * retry or redelivery**. A returned `err(...)` is the caller's signal to * decide whether to retry; the agent does not re-queue the message. * - **Errors** surface as `Result.err`, not as a throw for expected * conditions; the caller branches on the `Result`. * * @param msg - Message to handle * @returns Result with AgentResponse, or AgentError on failure (not retried) */ handleMessage(msg: AgentMessage): Promise>; /** * Initialize the agent with context. * @param ctx - Agent context * @returns Result with void or AgentError */ initialize(ctx: AgentContext): Promise>; /** * Cleanup agent resources. */ cleanup(): Promise; } /** * nexus-agents/config - Product Matrix Type Definitions * * Zod schemas and TypeScript interfaces for mapping product types * to skill bundles and expert weights for intelligent task routing. * * @module config/product-matrix/types */ /** * Supported product types for task routing. * Each type maps to a specific skill bundle and expert weight configuration. */ declare const PRODUCT_TYPES: readonly ["api", "web-service", "cli", "frontend-web", "mobile", "data-pipeline", "ml-service", "infra-module"]; type ProductType = (typeof PRODUCT_TYPES)[number]; /** * Task Analysis — Advocate Extensions (Issue #903) * * Deterministic heuristic functions for: * - Ambiguity scoring (0-1) * - Constraint extraction (time, quality, scope) * - Required capabilities inference (tools, experts) * * Separated from SharedTaskAnalyzer to respect the 400-line file limit. * * @module core/task-analysis/task-analysis-advocate */ /** * Extracted constraints from task description. */ interface TaskConstraints { /** Detected time constraint (e.g., "urgent", "by Friday") */ readonly time?: string; /** Detected quality level (e.g., "production-ready", "proof of concept") */ readonly quality?: string; /** Detected scope references (file paths, modules, PR numbers) */ readonly scope: readonly string[]; } /** * Inferred capabilities needed to fulfill the task. */ interface RequiredCapabilities { /** MCP tools likely needed */ readonly tools: readonly string[]; /** Expert roles likely valuable */ readonly experts: readonly string[]; } /** * Unified task analysis — classification views for routing. * Consolidates 5 independent analyzers per ADR-0004. * * Task classifier — one of 5 INTENTIONALLY SEPARATE classifiers (see #3299, by-design). * This one: `TaskTypeCategory` (9-category) → capability-based routing / expert selection. * Distinct from: task-type-classifier (reasoning|knowledge protocol selection), * cli-adapters/task-classifier (CLI fallback-chain ordering), coordination/task-features * (scaling topology), pipeline/adaptive-orchestrator (pipeline-stage selection). Keyword * overlap is superficial — the same token routes differently per layer and the output enums * are incompatible, so these are NOT consolidated. See #3299. * * @module core/task-analysis/shared-task-analyzer * (Source: Issue #574, ADR-0004; Issue #3299) */ /** * Reasoning vs Knowledge classification (arXiv:2502.19130). */ type ReasoningKnowledgeType = 'reasoning' | 'knowledge' | 'unknown'; /** * Complexity levels for routing (RouteLLM). */ type ComplexityLevel$1 = 'simple' | 'moderate' | 'complex' | 'expert'; /** * 9-type task taxonomy for capability-based routing. */ type TaskTypeCategory = 'architecture' | 'code_implementation' | 'code_review' | 'security_review' | 'test_generation' | 'documentation' | 'large_codebase' | 'bulk_operations' | 'general'; /** * Task capability flags. */ interface TaskCapabilities { readonly parallelizable: boolean; readonly multimodal: boolean; readonly codeGeneration: boolean; readonly budgetSensitive: boolean; readonly highContext: boolean; } /** * Unified analysis result combining all views. */ interface TaskAnalysisResult { /** Reasoning vs knowledge classification */ readonly reasoningType: ReasoningKnowledgeType; readonly reasoningConfidence: number; /** Complexity level */ readonly complexity: ComplexityLevel$1; readonly complexityScore: number; /** Task type category */ readonly taskType: TaskTypeCategory; readonly taskTypeConfidence: number; /** Capability flags */ readonly capabilities: TaskCapabilities; /** Estimated token count */ readonly estimatedTokens: number; /** Matched signals for observability */ readonly matchedSignals: readonly string[]; /** Ambiguity score (0=clear, 1=highly ambiguous). Issue #903. */ readonly ambiguityScore: number; /** Extracted constraints (time, quality, scope). Issue #903. */ readonly constraints: TaskConstraints; /** Inferred required capabilities (tools, experts). Issue #903. */ readonly requiredCapabilities: RequiredCapabilities; /** Detected product type from task content (optional) */ readonly detectedProductType?: ProductType; /** Confidence in the detected product type (0-1, optional) */ readonly productTypeConfidence?: number; } /** * Shared task analyzer interface. */ interface ISharedTaskAnalyzer { analyze(task: Task$1 | string): TaskAnalysisResult; getReasoningType(task: Task$1 | string): { type: ReasoningKnowledgeType; confidence: number; }; getComplexity(task: Task$1 | string): { level: ComplexityLevel$1; score: number; }; getTaskType(task: Task$1 | string): { type: TaskTypeCategory; confidence: number; }; getCapabilities(task: Task$1 | string): TaskCapabilities; estimateTokens(task: Task$1 | string): number; } /** * Capability Gap Detector (Issue #906) * * Cross-checks required capabilities from SharedTaskAnalyzer against * available system capabilities (MCP tools, expert roles, workflows). * * Deterministic — no external calls needed. Uses static registries. * * @module core/task-analysis/capability-gap-detector */ /** * Result of capability gap analysis. */ interface CapabilityGapReport { /** Capabilities that exist and can fulfill the request */ readonly available: AvailableCapabilities; /** Capabilities needed but not available */ readonly gaps: readonly CapabilityGap[]; /** Whether all required capabilities are available */ readonly allSatisfied: boolean; } /** * Available capabilities that matched requirements. */ interface AvailableCapabilities { readonly tools: readonly string[]; readonly experts: readonly string[]; } /** * Every kind of capability gap, as runtime data. * * The array is the single source and {@link CapabilityGapType} derives from it, * so a validator that needs to check a type at runtime cannot drift from the * union. It did: the persistence layer hardcoded `'tool' | 'expert'`, so every * persisted `tool_refusal` was discarded as malformed on load — the producer * wrote three entries and the next process read zero (#4651). */ declare const CAPABILITY_GAP_TYPES: readonly ["tool", "expert", "tool_refusal"]; /** What kind of capability gap this is. Derived from {@link CAPABILITY_GAP_TYPES}. */ type CapabilityGapType = (typeof CAPABILITY_GAP_TYPES)[number]; /** * A single capability gap with suggestion. */ interface CapabilityGap { /** * What kind of gap this is. * * `tool` and `expert` are *registry* gaps — a task required something the * registry does not contain. They are produced by {@link detectCapabilityGaps}, * which is currently unable to emit one: `requiredCapabilities` is drawn from * static lookup tables whose every entry is already available, so the required * set is a subset of the available set by construction (#4651). * * `tool_refusal` is a *capability* gap of a different kind — a tool that * exists, ran, and declined the work for a reason it can name. It is not * derived from the registry diff; producers record it directly at the point * of refusal. Added by the #4651 panel decision (option C, unanimous among * approvers) because the registry diff could not represent it. */ readonly type: CapabilityGapType; readonly name: string; readonly suggestion: string; } /** * Task Profile Adapter * * Provides compatibility bridge between SharedTaskAnalyzer's TaskAnalysisResult * and the legacy TaskProfile type used by router components. * * This adapter enables gradual migration from deprecated task-analyzer.ts * to the unified SharedTaskAnalyzer (ADR-0004, Issue #574, Issue #586). * * @module core/task-analysis/task-profile-adapter * (Source: Issue #586 - Migrate routers to SharedTaskAnalyzer) */ /** * Legacy TaskProfile type for backward compatibility. * * This mirrors the type from cli-adapters/task-analyzer.ts to enable * gradual migration without breaking existing router code. */ interface TaskProfile { /** Estimated input tokens required */ readonly contextRequired: number; /** Reasoning complexity on 0-10 scale */ readonly reasoningComplexity: number; /** Whether task involves code generation */ readonly codeGeneration: boolean; /** Whether task involves multimodal content (images, etc.) */ readonly multimodal: boolean; /** Whether task can be split into parallel subtasks */ readonly parallelizable: boolean; /** Whether cost should be minimized */ readonly budgetSensitive: boolean; /** Primary task type classification */ readonly taskType: TaskTypeCategory; /** Detected product type from task content (optional) */ readonly detectedProductType?: ProductType; } /** * Legacy TaskDomain type for expert-selector compatibility. * Maps to domain values used by expert definitions. */ type ExpertTaskDomain = 'code' | 'security' | 'architecture' | 'documentation' | 'testing' | 'infrastructure' | 'general'; /** * AvailableModelsCache (#2540 PR 6 of 8). * * Central, harness-driven view of what models the runtime can actually * dispatch to right now. PR 5 added `listModels()` on direct-API adapters * (Anthropic, Google, OpenAI gateway) and on the OpenCode CLI adapter; * this cache stitches those probes together into one queryable surface. * * Design invariants: * * 1. Sources are the source of truth — if a harness drops a model, * the registry never decides it's still routable. The * `ModelRegistry` (PR 1) answers "how should this model behave" * while this cache answers "is this model routable at all". * * 2. Stale-while-revalidate: serve the most recent successful result * while a refresh runs in the background, so callers never block on * a slow `models.list` round-trip. * * 3. One bad source must not poison the others. A failing `listModels` * logs and is excluded from the next snapshot; remaining sources * remain queryable. * * 4. No persistence. Process-local cache only — operators restart and * get a fresh probe. Persistence belongs in PR 7 if it's needed. */ /** * One adapter (CLI or API) that can be asked what models it currently has. * Exists so this cache doesn't have to know about IModelAdapter vs * ICliAdapter — both can adapt themselves to this minimal surface. */ interface AvailableModelsSource { /** Stable, human-readable identifier — e.g. `claude`, `gateway-openrouter`. */ readonly name: string; /** * Optional vendor-family hint — `anthropic` / `openai` / `google` / etc. * Used to pre-tag entries when the source's own model ids don't carry * a `provider/` prefix (Anthropic API, Google API). */ readonly providerHint?: string; /** Probe the underlying surface for currently available models. */ listModels(): Promise; } /** One row in the cache: model id + which source first reported it. */ interface AvailableModel { readonly id: string; readonly source: string; /** `provider/` prefix when the source uses one; otherwise the providerHint. */ readonly provider?: string; } interface AvailableModelsCacheOptions { readonly sources: readonly AvailableModelsSource[]; /** Freshness TTL (ms). Defaults to 5 minutes. */ readonly ttlMs?: number; /** Beyond this, callers block on the next refresh. Defaults to 25 minutes. */ readonly staleTtlMs?: number; /** Override `Date.now` for tests. */ readonly now?: () => number; } declare class AvailableModelsCache { private sources; private readonly ttlMs; private readonly staleTtlMs; private readonly now; private readonly states; constructor(options: AvailableModelsCacheOptions); /** * Register a source after construction. Used by adapter factories that * wire themselves into the default cache lazily as they're built. * Duplicate names are ignored (first registration wins, on the * assumption that the same factory might run twice in a test session). */ addSource(source: AvailableModelsSource): void; /** * Remove a previously-registered source. Used by tests + by factories * that want to drop a probe when an adapter is being disposed. */ removeSource(name: string): void; /** * Returns the union of every source's available models. Stale-while- * revalidate: serve fresh-or-stale immediately, refresh stale entries * in the background. First call (no cache yet) blocks on every source. */ getAll(): Promise; /** Models reported by one named source (subset of getAll). */ byProvider(sourceName: string): Promise; /** True iff some source currently reports the given model id. */ has(modelId: string): Promise; /** Force a synchronous refresh of every source — used after a 404. */ refresh(): Promise; /** * Probe one source. Returns: * - cached value if still fresh * - cached value AND kicks a background refresh if stale-but-not-expired * - blocks on the source if no cache or fully expired * * Source errors yield an empty list (logged) so one bad source can't * poison the union. */ private probeOne; private fetchSource; private getState; } /** * Get (or lazily construct) the process-default cache. Starts with no * sources — callers register them via `addSource`. Until at least one * source is added the cache returns empty snapshots, so every consumer * must treat an empty result as "unknown", not as "no models exist". */ declare function getDefaultAvailableModelsCache(): AvailableModelsCache; /** * Override the default cache. Useful for tests and for operators that * want a pre-populated cache wired at startup. */ declare function setDefaultAvailableModelsCache(cache: AvailableModelsCache | null): void; /** * nexus-agents/cli-adapters - Capability Type Definitions * * Capability types: ModelInfo, CapabilityProfile, CliTask, ICliAdapter, etc. * * (Source: cli-project_plan.md v2.1.0) * (Source: docs/research/cli-integration-architecture.md) */ /** * Model information from CLI. */ interface ModelInfo { /** Model identifier */ readonly id: string; /** Model display name */ readonly name: string; /** Maximum context window in tokens */ readonly contextWindow: number; /** Maximum output tokens */ readonly maxOutput?: number; /** Cost per 1M input tokens */ readonly costPerMillionInput?: number; /** Cost per 1M output tokens */ readonly costPerMillionOutput?: number; } /** * Base adapter constructor options shared by all CLI adapters. * CLI-specific adapters extend this with additional fields. */ interface BaseAdapterOptions { /** Model to use (defaults to the CLI's default from the canonical registry) */ readonly model?: string; /** Custom logger instance */ readonly logger?: ILogger; } /** * Capability profile for task routing. * (Source: cli-project_plan.md Capability Matching Matrix) */ interface CapabilityProfile$1 { /** Complex reasoning ability (0-10) */ readonly reasoning: number; /** Maximum context window in tokens */ readonly contextWindow: number; /** Code generation quality (0-10) */ readonly codeGeneration: number; /** Response speed (0-10, higher = faster) */ readonly speed: number; /** Cost efficiency (0-10, higher = cheaper) */ readonly cost: number; } /** * Task to execute on a CLI. */ interface CliTask { /** Task content/prompt */ readonly content: string; /** Optional system prompt */ readonly systemPrompt?: string; /** Preferred model (if any) */ readonly model?: string; /** Session ID for continuation */ readonly sessionId?: string; /** Maximum tokens to generate */ readonly maxTokens?: number; /** Timeout in milliseconds */ readonly timeoutMs?: number; /** Additional CLI-specific options */ readonly options?: Record; } /** * Internal resolved-options shape — every "default-able" field is * required, but `signal` stays optional because it's a per-call hook, * not a value with a default. Used by adapter internals (subprocess, * codex-mcp) and tests as the "resolved" execution options. Public * callers should keep using `ExecutionOptions` (everything optional). */ type ResolvedExecutionOptions = Required> & Pick; /** * Execution options for CLI adapters. */ interface ExecutionOptions$1 { /** Timeout in milliseconds */ readonly timeoutMs?: number; /** Whether to allow retries */ readonly allowRetry?: boolean; /** Maximum retry attempts */ readonly maxRetries?: number; /** Whether to track usage */ readonly trackUsage?: boolean; /** Progress callback invoked on subprocess stdout activity (Issue #1087). */ readonly onProgress?: (() => void) | undefined; /** * Cancellation signal (#3026 finding 2). When the signal aborts, the * adapter must cancel the in-flight execution promptly — for * subprocess adapters that means SIGTERM (with SIGKILL escalation * per #3026 finding 1). Without this, callers that use * `Promise.race([adapter.execute(task), timeout])` for cancellation * leak orphan subprocesses on race-loser: the timeout promise wins * the race but the adapter call keeps running, posting late results * into OutcomeStore + LinUCB state for a task whose decision has * already been recorded. * * Typed as `AbortSignal | undefined` (not `AbortSignal?`) so * `Required` — used pervasively by adapter * internals + tests as a resolved-options shape — keeps accepting * `signal: undefined` under `exactOptionalPropertyTypes`. */ readonly signal?: AbortSignal | undefined; } /** * CLI adapter interface. * Abstracts CLI integration with transport-agnostic execution. * (Source: cli-project_plan.md v2.1.0, Phase 2) */ interface ICliAdapter { /** CLI name */ readonly name: CliName; /** Transport type */ readonly transport: CliTransport; /** Capability profile */ readonly capabilities: CapabilityProfile$1; /** * Executes a task on the CLI. * * @param task - Task to execute * @param options - Execution options * @returns Result with response or error */ execute(task: CliTask, options?: ExecutionOptions$1): Promise>; /** * Performs a health check on the CLI. * * @returns Health status including version compatibility */ healthCheck(): Promise; /** * Gets current capacity/rate limit status. * * @returns Capacity status */ getCapacity(): Promise; /** * Gets CLI version. * * @returns Version string */ getVersion(): Promise; /** * Gets model information. * * @returns Model info */ getModelInfo(): ModelInfo; /** * Initializes the adapter (e.g., MCP connection). * Called before first use. */ initialize(): Promise; /** * Cleans up resources (e.g., subprocess, MCP connection). * Called on shutdown. */ dispose(): Promise; /** * (#2540) Optional: list models the underlying CLI installation/runtime * has available. Implementations should cache for ~5 min and throw on * failure so the caller can fall back. Adapters whose CLIs have no * native list surface (claude, codex, gemini) leave this undefined. */ listModels?(): Promise; } /** * (#2540) One row from a CLI's `models`-listing surface. `id` matches what * the CLI accepts as `--model`. `provider` is split out when the CLI uses * `provider/model` ids (e.g. opencode `anthropic/claude-3-5-sonnet`). */ interface CliModelInfo { readonly id: string; readonly provider?: string; } /** * Response parser interface for defensive parsing. * (Source: docs/research/cli-integration-architecture.md) */ interface ICliResponseParser { /** Parser name (for logging) */ readonly name: string; /** Supported version range (semver) */ readonly supportedVersionRange: string; /** * Parses raw CLI output to typed response. * * @param raw - Raw CLI output * @returns Parsed response or null if unrecognized */ parse(raw: string): T | null; /** * Extracts just the response text (most stable field). * * @param raw - Raw CLI output * @returns Response text or null */ extractResponse(raw: string): string | null; /** * Extracts a cost the CLI itself reported, in USD. * * OPTIONAL, and the optionality carries meaning (#5241). An ABSENT method * says "this vendor does not report cost" — true of codex, gemini, opencode * and agy. A PRESENT method returning `null` says "this vendor reports cost, * and this response carried none". Collapsing those two into a missing number * is what left `CliResponse.costUsd` with no producer while a consumer * (`budget-router`) fell back to an estimate under a field named `actual`. * * The value is a MEASUREMENT from the vendor, not a rate-derived figure, so * it does not pass through the token→USD pricing chain. * * @param raw - Raw CLI output * @returns Vendor-reported cost in USD, or null if this response carried none */ extractCostUsd?(raw: string): number | null; /** * Extracts an error-only message from a failure stream — when the CLI * surfaced an error event but no usable assistant content (so * {@link extractResponse} returns `null`). Optional: parsers that don't * distinguish error-only streams omit it, and the caller falls back to the * generic unparseable-output recovery. OpenCode's NDJSON `{"type":"error"}` * events are the motivating case — without this the message is misclassified * as PARSE_ERROR instead of NOT_AUTHENTICATED / RATE_LIMITED. * * @param raw - Raw CLI output * @returns The extracted error message, or `null` if none / not applicable */ extractErrorMessage?(raw: string): string | null; /** * Extracts token usage (may not be present). * * @param raw - Raw CLI output * @returns Token usage or null */ extractUsage(raw: string): TokenUsage$1 | null; /** * Extracts session ID (for resumption). * * @param raw - Raw CLI output * @returns Session ID or null */ extractSessionId(raw: string): string | null; } /** * Version requirements for CLIs. */ interface VersionRequirements { /** Minimum supported version */ readonly minimum: string; /** Recommended version */ readonly recommended: string; /** Known breaking versions */ readonly breaking: readonly string[]; } /** * CLI version requirements. * (Source: docs/research/cli-integration-architecture.md) */ declare const CLI_VERSION_REQUIREMENTS: Record; declare const DEFAULT_CAPABILITIES$1: Record; /** * Type definitions for the Task Specialization Matrix. * * Maps high-level task categories to preferred CLI tools based on * model strengths, inspired by StrongDM's Weather Report approach. * * @module config/task-specialization-types * (Source: Issue #858 — Multi-model task specialization) */ declare const TaskCategorySchema: z.ZodEnum<{ planning: "planning"; architecture: "architecture"; code_generation: "code_generation"; code_review: "code_review"; research: "research"; security_review: "security_review"; documentation: "documentation"; testing: "testing"; devops: "devops"; exploration: "exploration"; }>; type TaskCategory = z.infer; /** * nexus-agents/cli-adapters - Routing Type Definitions * * Routing types: Confidence, Cascade, Budget constraints, etc. * * (Source: cli-project_plan.md v2.1.0) * (Source: docs/research/cli-integration-architecture.md) */ /** * Budget constraints for task routing. * (Source: Issue #102 - PILOT pattern, arXiv:2508.21141) */ interface BudgetConstraint { /** Maximum tokens per task */ readonly maxTokens?: number; /** Maximum cost per task in USD */ readonly maxCostUsd?: number; /** Maximum latency per request in milliseconds */ readonly maxLatencyMs?: number; } /** * nexus-agents/cli-adapters - Routing Memory Types * * Interface contract for memory↔routing integration. * Enables MobiMem Evolution (#149) and Preference-Trained Routing (#148). * * Moved from core/types/routing-memory.ts to fix circular dependency (#286). * This module belongs in cli-adapters since it's fundamentally about routing. * * @module cli-adapters/routing-memory-types * (Source: Issue #238, Consensus Vote APPROVED 75%) * (Source: docs/proposals/interface-contract-238.md) */ /** * Error type for routing memory operations. * Self-contained to avoid cross-module dependencies. */ type RoutingMemoryErrorCode = 'STORAGE_FAILED' | 'RETRIEVAL_FAILED' | 'EXPORT_FAILED' | 'IMPORT_FAILED' | 'INVALID_DATA'; declare class RoutingMemoryError extends Error { readonly cause?: unknown | undefined; readonly code: RoutingMemoryErrorCode; constructor(message: string, code?: RoutingMemoryErrorCode, cause?: unknown | undefined); } /** * Summary of task profile for storage (avoids circular deps with TaskProfile). */ interface TaskProfileSummary { /** Estimated reasoning complexity (0-1) */ readonly reasoningComplexity: number; /** Context tokens required */ readonly contextRequired: number; /** Whether code generation is primary task */ readonly codeGeneration: boolean; /** Task type classification */ readonly taskType: 'reasoning' | 'knowledge' | 'code' | 'mixed'; } /** * Record of a routing decision. */ interface RoutingDecisionRecord { /** Unique decision ID */ readonly id: string; /** When the decision was made */ readonly timestamp: Date; /** Associated task ID */ readonly taskId: string; /** Task type classification */ readonly taskType: string; /** Summary of task profile */ readonly taskProfile: TaskProfileSummary; /** CLI selected for execution */ readonly selectedCli: CliName; /** Confidence score (0-1) */ readonly confidence: number; /** Alternative CLIs considered */ readonly alternatives: readonly CliName[]; /** Reasoning for selection */ readonly reason: string; /** Budget constraint applied (if any) */ readonly budgetConstraint?: BudgetConstraint; } /** * Record of a task outcome. */ interface TaskOutcomeRecord { /** Associated decision ID */ readonly decisionId: string; /** Whether task succeeded */ readonly success: boolean; /** Quality score (0-1) */ readonly qualityScore: number; /** Execution duration in milliseconds */ readonly durationMs: number; /** Token usage */ readonly tokenUsage: number; /** Number of retries */ readonly retryCount: number; /** Error category (if failed) */ readonly errorCategory?: string; } /** * Explicit preference signal from human or AI feedback. */ interface PreferenceSignal { /** Source of the preference */ readonly source: 'human' | 'ai' | 'implicit'; /** Preferred CLI for this task type */ readonly preferred: CliName; /** Rejected CLI (if comparative preference) */ readonly rejected?: CliName; /** Optional reasoning */ readonly reason?: string; /** Confidence in the preference (0-1) */ readonly confidence: number; } /** * Combined preference record for training. */ interface PreferenceRecord { /** The routing decision */ readonly decision: RoutingDecisionRecord; /** The task outcome */ readonly outcome: TaskOutcomeRecord; /** Explicit preference (if provided) */ readonly preference?: PreferenceSignal; /** Computed reward signal */ readonly computedReward: number; } /** * Filter for preference queries. */ interface PreferenceFilter { /** Filter by task type */ readonly taskType?: string; /** Filter by CLI name */ readonly cliName?: CliName; /** Records after this date */ readonly since?: Date; /** Records before this date */ readonly until?: Date; /** Minimum quality score */ readonly minQuality?: number; /** Filter by preference source */ readonly preferenceSource?: 'human' | 'ai' | 'implicit'; } /** * Step within an experience record. */ interface ExperienceStep { /** Step index */ readonly index: number; /** Action taken */ readonly action: string; /** Observation/result */ readonly observation: string; /** Duration in milliseconds */ readonly durationMs: number; } /** * Experience record for MobiMem Evolution. */ interface ExperienceRecord { /** Unique experience ID */ readonly id: string; /** When the experience occurred */ readonly timestamp: Date; /** Task type */ readonly taskType: string; /** Description of the task */ readonly taskDescription: string; /** Steps taken during execution */ readonly steps: readonly ExperienceStep[]; /** Whether the task succeeded */ readonly success: boolean; /** Key learnings from this experience */ readonly learnings: string; } /** * Action record for caching successful patterns. */ interface ActionRecord { /** Unique action ID */ readonly id: string; /** Task type this action applies to */ readonly taskType: string; /** Pattern description */ readonly pattern: string; /** Number of times this action was used */ readonly usageCount: number; /** Success rate (0-1) */ readonly successRate: number; /** Average duration in milliseconds */ readonly avgDurationMs: number; /** Last time this action was used */ readonly lastUsed: Date; } /** * Export format for routing memory. * Version field enables future schema migrations. */ interface RoutingMemoryExport { /** Schema version */ readonly version: '1.0'; /** When the export was created */ readonly exportedAt: Date; /** Preference records */ readonly preferences: readonly PreferenceRecord[]; /** Experience records */ readonly experiences: readonly ExperienceRecord[]; /** Action records */ readonly actions: readonly ActionRecord[]; } /** * Statistics for routing memory. */ interface RoutingMemoryStats$1 { /** Total preference records */ readonly preferenceCount: number; /** Total experience records */ readonly experienceCount: number; /** Total action records */ readonly actionCount: number; /** Oldest record timestamp */ readonly oldestRecord: Date | null; /** Newest record timestamp */ readonly newestRecord: Date | null; /** Estimated storage size in bytes */ readonly totalStorageBytes: number; } /** * Memory interface for routing-related data. * Bridges memory backend and routing systems. * * This interface enables: * - #148 Preference-Trained Routing: Store preferences and outcomes * - #149 MobiMem Evolution: Store experiences and action patterns * * @example * ```typescript * const routingMemory = createRoutingMemory(memoryBackend); * * // Store a routing decision and outcome * await routingMemory.storePreference(decision, outcome, preference); * * // Get preferences for training * const prefs = await routingMemory.getPreferences({ taskType: 'code' }, 100); * * // Store experience for MobiMem * await routingMemory.storeExperience(experience); * ``` */ interface IRoutingMemory$1 { /** * Store a routing decision with its outcome for preference learning. * @param decision - The routing decision made * @param outcome - The task outcome (success, quality, duration) * @param preference - Optional explicit preference signal */ storePreference(decision: RoutingDecisionRecord, outcome: TaskOutcomeRecord, preference?: PreferenceSignal): Promise>; /** * Retrieve preference data for training. * @param filter - Filter criteria for preferences * @param limit - Maximum records to return */ getPreferences(filter: PreferenceFilter, limit: number): Promise>; /** * Store an experience record for evolution. * @param experience - The experience to store */ storeExperience(experience: ExperienceRecord): Promise>; /** * Retrieve relevant experiences for a task. * @param query - Semantic query for experience retrieval * @param limit - Maximum experiences to return */ getExperiences(query: string, limit: number): Promise>; /** * Store a successful action pattern. * @param action - The action pattern to cache */ storeAction(action: ActionRecord): Promise>; /** * Retrieve cached actions for a task type. * @param taskType - Type of task * @param limit - Maximum actions to return */ getActions(taskType: string, limit: number): Promise>; /** * Export all routing memory for training or backup. */ export(): Promise>; /** * Import routing memory from export. * @param data - The exported data to import */ import(data: RoutingMemoryExport): Promise>; /** * Get memory statistics. */ getStats(): Promise>; } /** * nexus-agents/agents - OrchestrationObserver Types * * Type definitions for real-time orchestration visibility. * Provides structured types for agent states, metrics, and routing decisions. * * (Source: Issue #187 - OrchestrationObserver for orchestration visibility) * (Renamed from SwarmObserver in Issue #251 to avoid collision with observability/swarm-observer.ts) * * @module agents/observability/orchestration-observer-types */ /** * Agent execution states. */ declare const AgentStateSchema: z.ZodEnum<{ error: "error"; thinking: "thinking"; idle: "idle"; waiting: "waiting"; executing: "executing"; }>; type AgentState$1 = z.infer; /** * Tracked agent information. */ interface TrackedAgent { readonly id: string; readonly role: string; state: AgentState$1; currentTask?: string | undefined; lastUpdated: string; taskCount: number; errorCount: number; } /** * Captured routing decision for audit and analysis. */ interface RoutingDecision$2 { readonly timestamp: string; readonly taskId: string; readonly taskDescription: string; readonly selectedCli: CliName; readonly confidence: number; readonly reason: string; readonly alternatives: readonly CliName[]; readonly stagesExecuted: readonly string[]; readonly decisionTimeMs: number; readonly withinBudget?: boolean | undefined; readonly topsisScore?: number | undefined; readonly ucbScore?: number | undefined; } /** * Running token totals for an observability SESSION, aggregated across calls. * * Named to distinguish it from the per-call `TokenUsage` in * `core/types/model.ts` (#4440). The two shared a name and a shape while * modelling different things — session aggregate vs. one call's usage — and * `exports/observability.ts` already had to alias this one as * `ObserverTokenUsage` to avoid the clash. That collision is not harmless: it * led me to file #4439 claiming three duplicate per-call types when there were * two, and the third was this. */ interface SessionTokenTotals { inputTokens: number; outputTokens: number; totalTokens: number; } /** * Cost tracking per session. * * `totalCostUsd` sums only MEASURED calls. A call whose arm cannot be priced * — a gateway arm with no usable `NEXUS_GATEWAY_COST` declaration (#6399) — * adds nothing to it and increments `unpricedCalls` instead, so a total over * unmeasured traffic reads as partial rather than as $0. `costPerModel` keeps * its published CLI-slot key; `costPerArm` is keyed by the observed ARM, so a * gateway's cost is never folded into its display slot. */ interface CostMetrics { totalCostUsd: number; /** Per CLI slot, as published. A gateway arm never lands here. */ costPerModel: Map; /** Per observed arm (#6399): CLI slots, vendor arms and gateway arms. */ costPerArm: Map; /** Calls `totalCostUsd` does NOT cover. Zero means every call was priced. */ unpricedCalls: number; } /** * Session-level metrics. */ interface SessionMetrics { readonly sessionId: string; startedAt: string; completedAt?: string | undefined; durationMs: number; taskCount: number; successCount: number; failureCount: number; tokenUsage: SessionTokenTotals; costMetrics: CostMetrics; routingDecisions: number; eventsProcessed: number; } /** * Aggregate orchestration statistics. */ interface OrchestrationStats { /** Total sessions observed */ totalSessions: number; /** Currently active sessions */ activeSessions: number; /** Total tasks processed */ totalTasks: number; /** Success rate (0-1) */ successRate: number; /** Average task duration in ms */ avgTaskDurationMs: number; /** Routing decisions per CLI */ routingDistribution: Record; /** Total tokens used */ totalTokens: number; /** Total cost (estimated) */ totalCostUsd: number; /** Events processed */ eventsProcessed: number; /** Observer uptime in ms */ uptimeMs: number; /** Consensus voting statistics (Issue #552) */ consensus: ConsensusStats; } /** * Consensus voting statistics tracked by observer. * (Source: Issue #552 - Wire up consensus event handlers) */ interface ConsensusStats { /** Total votes requested */ votesRequested: number; /** Total votes cast */ votesCast: number; /** Consensus decisions reached */ consensusReached: number; /** Approvals vs rejections */ decisions: { approved: number; rejected: number; abstained: number; }; /** Unanimity rate (0-1) */ unanimityRate: number; } /** * OrchestrationObserver event types for visualization hooks. */ type OrchestrationObserverEvent = { type: 'agent_state_changed'; agentId: string; state: AgentState$1; previousState: AgentState$1; } | { type: 'routing_decision'; decision: RoutingDecision$2; } | { type: 'session_started'; sessionId: string; pattern: string; } | { type: 'session_completed'; sessionId: string; success: boolean; durationMs: number; } | { type: 'metrics_updated'; metrics: OrchestrationStats; } | { type: 'error'; source: string; error: string; }; /** * Observer event listener function. */ type OrchestrationObserverListener = (event: OrchestrationObserverEvent) => void; /** * OrchestrationObserver interface for dependency injection. */ interface IOrchestrationObserver { /** Start observing the event bus */ start(): void; /** Stop observing and cleanup */ stop(): void; /** Get current agent states */ getAgentStates(): readonly TrackedAgent[]; /** Get routing decision history */ getRoutingHistory(limit?: number): readonly RoutingDecision$2[]; /** Get session metrics */ getSessionMetrics(sessionId?: string): readonly SessionMetrics[]; /** Get aggregate orchestration statistics */ getStats(): OrchestrationStats; /** Add event listener for visualization */ addEventListener(listener: OrchestrationObserverListener): void; /** Remove event listener */ removeEventListener(listener: OrchestrationObserverListener): void; /** Record a routing decision manually (for non-event-bus integrations) */ recordRoutingDecision(decision: RoutingDecision$2): void; /** Record token usage for a session on a CLI slot. */ recordTokenUsage(sessionId: string, model: CliName, tokens: SessionTokenTotals): void; /** * Record token usage for a session on any observed ARM (#6399): a CLI * slot, a vendor arm, or a gateway arm. A gateway must come through here, * not as its display slot — `recordTokenUsage('opencode', …)` would price * it as that slot's default model. */ recordArmTokenUsage(sessionId: string, arm: ObservedArmId, tokens: SessionTokenTotals): void; /** Check if observer is active */ isActive(): boolean; } /** * nexus-agents/cli-adapters - TOPSIS Types * * Types for TOPSIS (Technique for Order of Preference by Similarity * to Ideal Solution) multi-criteria decision making algorithm. * * @module cli-adapters/topsis-types * (Source: arXiv:2509.07571, Issue #146) */ /** * A criterion for multi-criteria decision making. */ interface TopsisCredential { /** Criterion name (e.g., 'cost', 'latency', 'quality') */ readonly name: string; /** Weight for this criterion (0-1, should sum to 1 across all criteria) */ readonly weight: number; /** Whether higher values are better (true) or lower is better (false) */ readonly beneficial: boolean; } /** * Configuration for TOPSIS router. */ interface TopsisConfig { /** Criteria with weights (must sum to 1.0) */ readonly criteria: readonly TopsisCredential[]; /** Minimum acceptable quality score (0-10) */ readonly minQualityThreshold: number; /** Maximum acceptable latency in ms (optional) */ readonly maxLatencyMs?: number; /** Maximum acceptable cost per request in USD (optional) */ readonly maxCostPerRequest?: number; /** Whether to log detailed scoring info */ readonly verbose: boolean; } /** * nexus-agents/cli-adapters - ZeroRouter Types * * Type definitions for the ZeroRouter universal difficulty space routing. * ZeroRouter creates a unified difficulty metric across diverse task types, * enabling better model selection across domains. * * @module cli-adapters/zero-router-types * (Source: Issue #338) */ /** * Difficulty dimensions for task analysis. * Each dimension represents a different aspect of task difficulty. */ declare const DifficultyDimensionSchema: z.ZodEnum<{ reasoning: "reasoning"; knowledge: "knowledge"; precision: "precision"; creativity: "creativity"; context_length: "context_length"; }>; type DifficultyDimension = z.infer; /** * Difficulty space representation (normalized 0-1 across all dimensions). */ declare const DifficultySpaceSchema: z.ZodObject<{ reasoning: z.ZodNumber; knowledge: z.ZodNumber; creativity: z.ZodNumber; precision: z.ZodNumber; context_length: z.ZodNumber; }, z.core.$strip>; type DifficultySpace = z.infer; /** * Difficulty level classification based on aggregate score. */ type DifficultyLevel = 'easy' | 'medium' | 'hard'; /** * Model tier based on capability/cost trade-off. */ type ModelTier$1 = 'fast' | 'balanced' | 'powerful'; /** * Result of difficulty estimation. */ interface DifficultyEstimate { /** Difficulty values per dimension (all 0-1) */ readonly dimensions: DifficultySpace; /** Aggregated difficulty score (0-1) */ readonly aggregateScore: number; /** Classified difficulty level */ readonly level: DifficultyLevel; /** Recommended model tier based on difficulty */ readonly recommendedTier: ModelTier$1; /** Confidence in the estimate (0-1) */ readonly confidence: number; /** Dominant difficulty dimension */ readonly dominantDimension: DifficultyDimension; } /** * Outcome record for calibration. */ interface DifficultyOutcome { /** Task content hash (for deduplication) */ readonly taskHash: string; /** Estimated difficulty at routing time */ readonly estimatedDifficulty: number; /** CLI that was selected */ readonly selectedCli: CliName; /** Whether the task succeeded */ readonly success: boolean; /** Quality score if available (0-1) */ readonly qualityScore?: number; /** Actual execution time in ms */ readonly executionTimeMs?: number; /** Timestamp of the outcome */ readonly timestamp: number; } /** * Calibration statistics for self-improvement. */ interface CalibrationStats { /** Total outcomes recorded */ readonly totalOutcomes: number; /** Mean absolute error of difficulty estimates */ readonly meanAbsoluteError: number; /** Correlation between estimated difficulty and actual success rate */ readonly difficultySuccessCorrelation: number; /** Success rate by difficulty level */ readonly successRateByLevel: Readonly>; /** Average quality score by difficulty level */ readonly avgQualityByLevel: Readonly>; /** Calibration bias (-1 to 1, negative = underestimating difficulty) */ readonly calibrationBias: number; } /** * Configuration for ZeroRouter. */ declare const ZeroRouterConfigSchema: z.ZodObject<{ thresholds: z.ZodDefault>; weights: z.ZodDefault>; difficultyToTier: z.ZodDefault, z.ZodEnum<{ balanced: "balanced"; fast: "fast"; powerful: "powerful"; }>>>; tierToClis: z.ZodDefault, z.ZodArray>>>; enableCalibration: z.ZodDefault; maxCalibrationOutcomes: z.ZodDefault; minCalibrationOutcomes: z.ZodDefault; verbose: z.ZodDefault; }, z.core.$strip>; type ZeroRouterConfig = z.infer; /** * Routing decision from ZeroRouter. */ interface ZeroRoutingDecision { /** Estimated difficulty */ readonly difficulty: DifficultyEstimate; /** Selected CLI based on difficulty */ readonly selectedCli: CliName; /** Recommended model tier */ readonly tier: ModelTier$1; /** Alternative CLIs in preference order */ readonly alternatives: readonly CliName[]; /** Reasoning for the decision */ readonly reason: string; /** Whether calibration was applied */ readonly calibrationApplied: boolean; /** Calibration adjustment applied (if any) */ readonly calibrationAdjustment?: number | undefined; } /** * nexus-agents/cli-adapters - ZeroRouter * * Universal difficulty space routing for intelligent model selection. * Creates a unified difficulty metric across diverse task types, * enabling better model selection across domains. * * @module cli-adapters/zero-router * (Source: Issue #338) */ /** * Interface for ZeroRouter for dependency injection. */ interface IZeroRouter { estimateDifficulty(task: CliTask): DifficultyEstimate; routeByDifficulty(task: CliTask, availableClis?: CliName[]): ZeroRoutingDecision; calibrate(outcome: DifficultyOutcome): void; getCalibrationStats(): CalibrationStats; getConfig(): ZeroRouterConfig; } /** * nexus-agents/cli-adapters - Latency Tracker Types * * Type definitions and Zod schemas for CLI latency tracking. * Tracks execution times for smarter routing decisions. * * @module cli-adapters/latency-tracker-types * (Source: Issue #361 - CLI latency tracking for routing) */ /** * Configuration schema for LatencyTracker. */ declare const LatencyTrackerConfigSchema: z.ZodObject<{ windowSize: z.ZodDefault; decayFactor: z.ZodDefault; maxSampleAgeMs: z.ZodDefault; percentiles: z.ZodDefault>; }, z.core.$strip>; type LatencyTrackerConfig = z.infer; /** * Latency statistics for a single CLI. */ interface LatencyStats { /** Number of samples in the window */ readonly count: number; /** Arithmetic mean of latencies */ readonly avg: number; /** Minimum latency observed */ readonly min: number; /** Maximum latency observed */ readonly max: number; /** 50th percentile (median) */ readonly p50: number; /** 95th percentile */ readonly p95: number; /** 99th percentile */ readonly p99: number; /** Standard deviation */ readonly stdDev: number; /** Time-weighted average (recent samples weighted more) */ readonly weightedAvg: number; /** Success rate (0-1) */ readonly successRate: number; /** Timestamp of the oldest sample */ readonly oldestSampleAt: number | undefined; /** Timestamp of the newest sample */ readonly newestSampleAt: number | undefined; } /** * Latency-based routing score for a CLI. */ interface LatencyScore { /** The CLI being scored */ readonly cli: CliName; /** Normalized score (0-1, higher is better/faster) */ readonly score: number; /** Confidence in the score (0-1, based on sample count) */ readonly confidence: number; /** Raw weighted average latency */ readonly weightedAvgMs: number; /** Whether enough data exists for reliable scoring */ readonly hasReliableData: boolean; } /** * Overall tracker statistics for observability. */ interface LatencyTrackerStats { /** Stats per CLI */ readonly perCli: Readonly>; /** Total samples across all CLIs */ readonly totalSamples: number; /** Total recordings made (including evicted) */ readonly totalRecordings: number; /** Number of samples evicted due to age */ readonly evictedByAge: number; /** Number of samples evicted due to window size */ readonly evictedByWindow: number; } /** * Interface for latency tracker dependency injection. */ interface ILatencyTracker { /** Record a latency measurement for a CLI */ record(cli: CliName, durationMs: number, success?: boolean): void; /** Get statistics for a specific CLI */ getStats(cli: CliName): LatencyStats; /** Get latency-based routing scores for all CLIs */ getScores(clis: readonly CliName[]): readonly LatencyScore[]; /** Get a single score for a CLI */ getScore(cli: CliName): LatencyScore; /** Get overall tracker statistics */ getTrackerStats(): LatencyTrackerStats; /** Clear all samples for a specific CLI */ clear(cli: CliName): void; /** Clear all samples for all CLIs */ clearAll(): void; } /** * Database Type Definitions * * Unified interfaces for SQLite database operations. * Consolidates duplicate definitions from session-storage, learning, and memory modules. * * @module core/types/database-types */ /** * Minimal interface for a prepared SQLite statement. * Satisfied by `node:sqlite`'s StatementSync (#5388). */ interface ISQLiteStatement { /** * Execute the statement with the given parameters. * Returns information about changes made. */ run(...params: unknown[]): ISQLiteRunResult; /** * Get a single row matching the statement. * Returns undefined if no match. */ get(...params: unknown[]): T | undefined; /** * Get all rows matching the statement. */ all(...params: unknown[]): T[]; } /** * Result of running a SQLite statement. */ interface ISQLiteRunResult { /** Number of rows changed */ readonly changes: number; /** ID of the last inserted row (optional, depends on operation) */ readonly lastInsertRowid?: number | bigint; } /** * Minimal interface for a SQLite database handle. * Satisfied by `node:sqlite`'s DatabaseSync via `openSqliteDatabase` (#5388). * ~30 helper signatures and ~12 test doubles are written against this, which is * why swapping the engine underneath did not ripple outward. */ interface ISQLiteDatabase { /** * Execute raw SQL statements (typically for DDL or multiple statements). */ exec(sql: string): void; /** * Prepare a parameterized statement for execution. */ prepare(sql: string): ISQLiteStatement; /** * Close the database connection. */ close(): void; } /** * nexus-agents/mcp - Rate Limiter Middleware * * Token bucket implementation for rate limiting MCP tool calls. * Prevents abuse and ensures fair resource usage. * * (Source: Token Bucket Algorithm, RFC 6585) */ /** * Configuration for the token bucket rate limiter. */ interface RateLimiterConfig$1 { /** Maximum number of tokens in the bucket */ readonly capacity: number; /** Number of tokens added per interval */ readonly refillRate: number; /** Interval in milliseconds between token refills (default: 1000ms) */ readonly refillIntervalMs?: number; /** Optional logger instance */ readonly logger?: ILogger; /** Optional identifier for logging */ readonly name?: string; } /** * Current state of the rate limiter. */ interface RateLimiterState { /** Current number of available tokens */ readonly tokens: number; /** Capacity of the bucket */ readonly capacity: number; /** Time until next token is available (0 if tokens available) */ readonly nextTokenMs: number; } /** * Token bucket rate limiter implementation. * * The token bucket algorithm allows for bursting up to the capacity, * while maintaining a steady-state rate equal to the refill rate. * * @example * ```typescript * const limiter = new RateLimiter({ * capacity: 100, * refillRate: 10, * refillIntervalMs: 1000, * }); * * if (limiter.tryAcquire()) { * // Proceed with operation * } else { * // Rate limited, reject or queue * } * ``` */ declare class RateLimiter$1 { private tokens; private readonly capacity; private readonly refillRate; private readonly refillIntervalMs; private lastRefillTime; private readonly logger; private readonly name; constructor(config: RateLimiterConfig$1); /** * Refills tokens based on elapsed time. * Called automatically before each acquire attempt. */ private refill; /** * Attempts to acquire a token. * * @param count - Number of tokens to acquire (default: 1) * @returns True if tokens were acquired, false if rate limited */ tryAcquire(count?: number): boolean; /** * Gets the current state of the rate limiter. * * @returns The current rate limiter state */ getState(): RateLimiterState; /** * Resets the rate limiter to full capacity. * Useful for testing or after configuration changes. */ reset(): void; } /** * Creates a rate limiter with default settings suitable for MCP tools. * * Default configuration: * - Capacity: 100 tokens * - Refill rate: 10 tokens per second * * @param name - Optional name for the rate limiter * @param logger - Optional logger instance * @returns A configured RateLimiter instance */ declare function createDefaultRateLimiter(name?: string, logger?: ILogger): RateLimiter$1; /** * nexus-agents/config - Core Configuration Schemas * * Basic infrastructure schemas: Logging, Provider, Model configuration. */ /** * Logging configuration schema. */ declare const LoggingConfigSchema: z.ZodObject<{ level: z.ZodDefault>; format: z.ZodDefault>; destination: z.ZodDefault>; filePath: z.ZodOptional; }, z.core.$strip>; type LoggingConfig = z.infer; /** * Provider configuration schema. */ declare const ProviderConfigSchema: z.ZodObject<{ apiKey: z.ZodOptional; baseUrl: z.ZodOptional; timeout: z.ZodDefault; maxRetries: z.ZodDefault; }, z.core.$strip>; type ProviderConfig = z.infer; /** * Model tier configuration. */ declare const ModelTiersSchema: z.ZodObject<{ fast: z.ZodArray; balanced: z.ZodArray; powerful: z.ZodArray; }, z.core.$strip>; type ModelTiers = z.infer; /** * Model configuration schema. */ declare const ModelConfigSchema: z.ZodObject<{ default: z.ZodString; tiers: z.ZodObject<{ fast: z.ZodArray; balanced: z.ZodArray; powerful: z.ZodArray; }, z.core.$strip>; providers: z.ZodOptional; baseUrl: z.ZodOptional; timeout: z.ZodDefault; maxRetries: z.ZodDefault; }, z.core.$strip>>>; }, z.core.$strip>; type ModelConfig = z.infer; /** * Workflow configuration schema. */ declare const WorkflowConfigSchema: z.ZodObject<{ templatesDir: z.ZodDefault; timeout: z.ZodDefault; maxParallel: z.ZodDefault; }, z.core.$strip>; type WorkflowConfig = z.infer; /** * nexus-agents/config - Expert Configuration Schemas * * Schemas for expert definitions, custom experts, and related constants. */ /** * Legacy expert definition schema (for backwards compatibility). * Use CustomExpertDefinitionSchema for new implementations. */ declare const ExpertDefinitionSchema: z.ZodObject<{ prompt: z.ZodString; tier: z.ZodDefault>; temperature: z.ZodDefault; tools: z.ZodOptional>; }, z.core.$strip>; type ExpertDefinition$1 = z.infer; /** * Expert configuration schema. */ declare const ExpertConfigSchema$1: z.ZodObject<{ builtin: z.ZodDefault; custom: z.ZodOptional>; domain: z.ZodDefault>; secondaryDomains: z.ZodOptional>>; capabilities: z.ZodDefault>; temperature: z.ZodDefault; tools: z.ZodOptional>; description: z.ZodOptional; weight: z.ZodDefault; available: z.ZodDefault; }, z.core.$strip>>>; }, z.core.$strip>; type ExpertConfig$1 = z.infer; /** * nexus-agents/config - Security Configuration Schemas * * Schemas for security, policy, sandbox, timeout, and rate limiting. */ /** * Security configuration schema. */ declare const SecurityConfigSchema: z.ZodObject<{ allowedPaths: z.ZodDefault>; blockedPatterns: z.ZodDefault>; rateLimit: z.ZodDefault; requestsPerMinute: z.ZodDefault; perTool: z.ZodOptional; refillRate: z.ZodDefault; refillIntervalMs: z.ZodDefault; }, z.core.$strip>>>; }, z.core.$strip>>; secretsFile: z.ZodOptional; policy: z.ZodOptional>; policyMode: z.ZodDefault>; }, z.core.$strip>>; sandbox: z.ZodOptional>; fallbackToPolicy: z.ZodDefault; dockerImage: z.ZodOptional; networkEnabled: z.ZodDefault; }, z.core.$strip>>; timeout: z.ZodOptional; maxTimeoutMs: z.ZodDefault; enableLogging: z.ZodDefault; uriValidation: z.ZodDefault; perToolTimeout: z.ZodOptional>; }, z.core.$strip>>; toolAllowlist: z.ZodOptional>; audit: z.ZodOptional; logDir: z.ZodOptional; minSeverity: z.ZodDefault>; enableHashChain: z.ZodDefault; maxFileSizeBytes: z.ZodDefault; maxFiles: z.ZodDefault; }, z.core.$strip>>; auth: z.ZodOptional; method: z.ZodDefault>; tokenHeader: z.ZodDefault; tokenFile: z.ZodOptional; }, z.core.$strip>>; }, z.core.$strip>; type SecurityConfig = z.infer; /** * nexus-agents/config - Observability Configuration Schemas * * Schemas for EventBus and observability configuration. */ /** * EventBus observability configuration schema. * * Controls EventBus integration with MCP server for agent-to-agent * communication visibility in Claude Desktop context. * * (Source: Issue #307 - EventBus MCP integration) */ declare const EventBusConfigSchema: z.ZodObject<{ enabled: z.ZodDefault; maxHistorySize: z.ZodDefault; subscriptions: z.ZodDefault; agent: z.ZodDefault; protocol: z.ZodDefault; session: z.ZodDefault; message: z.ZodDefault; byzantine: z.ZodDefault; }, z.core.$strip>>; logging: z.ZodDefault>; importantEventLevel: z.ZodDefault>; }, z.core.$strip>>; }, z.core.$strip>; type EventBusConfig = z.infer; /** * nexus-agents/config - Configuration Schemas * * Aggregation module that re-exports all configuration schemas. * Individual schema categories are organized in separate files: * - schemas-core.ts: Logging, Provider, Model, Workflow * - schemas-expert.ts: Expert definitions and constants * - schemas-security.ts: Security, Policy, Sandbox, Timeout, RateLimit * - schemas-observability.ts: EventBus, Observability */ /** * Complete application configuration schema. */ declare const AppConfigSchema: z.ZodObject<{ models: z.ZodObject<{ default: z.ZodString; tiers: z.ZodObject<{ fast: z.ZodArray; balanced: z.ZodArray; powerful: z.ZodArray; }, z.core.$strip>; providers: z.ZodOptional; baseUrl: z.ZodOptional; timeout: z.ZodDefault; maxRetries: z.ZodDefault; }, z.core.$strip>>>; }, z.core.$strip>; experts: z.ZodOptional; custom: z.ZodOptional>; domain: z.ZodDefault>; secondaryDomains: z.ZodOptional>>; capabilities: z.ZodDefault>; temperature: z.ZodDefault; tools: z.ZodOptional>; description: z.ZodOptional; weight: z.ZodDefault; available: z.ZodDefault; }, z.core.$strip>>>; }, z.core.$strip>>; workflows: z.ZodOptional; timeout: z.ZodDefault; maxParallel: z.ZodDefault; }, z.core.$strip>>; security: z.ZodOptional>; blockedPatterns: z.ZodDefault>; rateLimit: z.ZodDefault; requestsPerMinute: z.ZodDefault; perTool: z.ZodOptional; refillRate: z.ZodDefault; refillIntervalMs: z.ZodDefault; }, z.core.$strip>>>; }, z.core.$strip>>; secretsFile: z.ZodOptional; policy: z.ZodOptional>; policyMode: z.ZodDefault>; }, z.core.$strip>>; sandbox: z.ZodOptional>; fallbackToPolicy: z.ZodDefault; dockerImage: z.ZodOptional; networkEnabled: z.ZodDefault; }, z.core.$strip>>; timeout: z.ZodOptional; maxTimeoutMs: z.ZodDefault; enableLogging: z.ZodDefault; uriValidation: z.ZodDefault; perToolTimeout: z.ZodOptional>; }, z.core.$strip>>; toolAllowlist: z.ZodOptional>; audit: z.ZodOptional; logDir: z.ZodOptional; minSeverity: z.ZodDefault>; enableHashChain: z.ZodDefault; maxFileSizeBytes: z.ZodDefault; maxFiles: z.ZodDefault; }, z.core.$strip>>; auth: z.ZodOptional; method: z.ZodDefault>; tokenHeader: z.ZodDefault; tokenFile: z.ZodOptional; }, z.core.$strip>>; }, z.core.$strip>>; logging: z.ZodOptional>; format: z.ZodDefault>; destination: z.ZodDefault>; filePath: z.ZodOptional; }, z.core.$strip>>; observability: z.ZodOptional; maxHistorySize: z.ZodDefault; subscriptions: z.ZodDefault; agent: z.ZodDefault; protocol: z.ZodDefault; session: z.ZodDefault; message: z.ZodDefault; byzantine: z.ZodDefault; }, z.core.$strip>>; logging: z.ZodDefault>; importantEventLevel: z.ZodDefault>; }, z.core.$strip>>; }, z.core.$strip>>; swarmObserverMaxEvents: z.ZodDefault; }, z.core.$strip>>; routing: z.ZodOptional; zeroRouter: z.ZodDefault; preferenceRouting: z.ZodDefault; topsisRanking: z.ZodDefault; linucbSelection: z.ZodDefault; latencyTracking: z.ZodDefault; routingMemory: z.ZodDefault; confidenceCascade: z.ZodDefault; capabilityMatch: z.ZodDefault; qualityConstraint: z.ZodDefault; resourceStrategy: z.ZodDefault; strategyDistillation: z.ZodDefault; }, z.core.$strip>>; budget: z.ZodOptional; maxCostUsd: z.ZodOptional; maxLatencyMs: z.ZodOptional; taskClassMaxCostUsd: z.ZodOptional & z.core.$partial, z.ZodNumber>>; }, z.core.$strip>>; topsis: z.ZodOptional>>; minQualityThreshold: z.ZodDefault; maxLatencyMs: z.ZodOptional; maxCostPerRequest: z.ZodOptional; verbose: z.ZodDefault; }, z.core.$strip>>; zeroRouter: z.ZodOptional; hardLowerBound: z.ZodDefault; }, z.core.$strip>>; weights: z.ZodOptional; knowledge: z.ZodDefault; creativity: z.ZodDefault; precision: z.ZodDefault; context_length: z.ZodDefault; }, z.core.$strip>>; difficultyToTier: z.ZodOptional, z.ZodEnum<{ balanced: "balanced"; fast: "fast"; powerful: "powerful"; }>>>; tierToClis: z.ZodOptional, z.ZodArray>>>; enableCalibration: z.ZodDefault; maxCalibrationOutcomes: z.ZodDefault; minCalibrationOutcomes: z.ZodDefault; verbose: z.ZodDefault; }, z.core.$strip>>; latencyTracker: z.ZodOptional; decayFactor: z.ZodDefault; maxSampleAgeMs: z.ZodDefault; percentiles: z.ZodDefault>; }, z.core.$strip>>; routingMemory: z.ZodOptional; confidenceThreshold: z.ZodDefault; successRateThreshold: z.ZodDefault; actionCacheMaxAgeMs: z.ZodDefault; }, z.core.$strip>>; linucb: z.ZodOptional; maxDecisionTimeMs: z.ZodDefault; }, z.core.$strip>>; preference: z.ZodOptional; }, z.core.$strip>>; latencyScoreWeight: z.ZodDefault; }, z.core.$strip>>; skills: z.ZodOptional; maxSkills: z.ZodDefault; minSuccessRateForRetention: z.ZodDefault; executionsBeforeEvaluation: z.ZodDefault; enablePruning: z.ZodDefault; trackExecutionHistory: z.ZodDefault; maxHistoryPerSkill: z.ZodDefault; externalPacks: z.ZodOptional; }, z.core.$strip>>>; }, z.core.$strip>>; sica: z.ZodOptional; minExecutionsForImprovement: z.ZodDefault; improvementThreshold: z.ZodDefault; maxActiveVersions: z.ZodDefault; autoSelectBest: z.ZodDefault; improvementCooldownMs: z.ZodDefault; enableObservability: z.ZodDefault; }, z.core.$strip>>; gateway: z.ZodOptional; tierOverrides: z.ZodOptional>>; upstreamServers: z.ZodOptional; args: z.ZodDefault>; env: z.ZodOptional>; lazy: z.ZodDefault; timeoutMs: z.ZodDefault; }, z.core.$strip>>>; }, z.core.$strip>>; memory: z.ZodOptional; decayIntervalMs: z.ZodOptional; beliefMaxAgeDays: z.ZodOptional; agenticMaxEntries: z.ZodOptional; agenticImportanceThreshold: z.ZodOptional; adaptivePriorityThreshold: z.ZodOptional; mobimemEvictOnDecay: z.ZodOptional; checkCrossReferences: z.ZodOptional; crossReferenceGracePeriodMs: z.ZodOptional; }, z.core.$strip>>; }, z.core.$strip>>; }, z.core.$strip>; type AppConfig = z.infer; /** * Default configuration values. */ declare const defaultConfig: Partial; /** * Type definitions for task outcome tracking. * * Records the result of each model delegation or consensus vote * to enable performance measurement across CLIs and task categories. * * @module orchestration/outcomes/outcome-types * (Source: Issue #861 — Task outcome tracking) */ /** Failure category for failed task outcomes (Issue #1025). */ declare const OutcomeFailureCategorySchema: z.ZodEnum<{ timeout: "timeout"; parse: "parse"; connection: "connection"; execution: "execution"; rate_limit: "rate_limit"; unknown: "unknown"; validation: "validation"; crash: "crash"; authentication: "authentication"; adapter_unavailable: "adapter_unavailable"; generic: "generic"; }>; /** Schema for a single recorded task outcome. */ declare const TaskOutcomeSchema$1: z.ZodObject<{ id: z.ZodString; cli: z.ZodUnion, z.ZodEnum<{ "api:anthropic": "api:anthropic"; "api:google": "api:google"; "api:openai": "api:openai"; "api:custom-openai": "api:custom-openai"; }>, z.ZodLiteral<"unknown">]>; cliSource: z.ZodOptional>; category: z.ZodEnum<{ planning: "planning"; architecture: "architecture"; code_generation: "code_generation"; code_review: "code_review"; research: "research"; security_review: "security_review"; documentation: "documentation"; testing: "testing"; devops: "devops"; exploration: "exploration"; }>; model: z.ZodString; success: z.ZodBoolean; durationMs: z.ZodNumber; timestamp: z.ZodString; qualitySignals: z.ZodOptional>; failureCategory: z.ZodOptional>; errorMessage: z.ZodOptional; source: z.ZodEnum<{ delegate: "delegate"; consensus: "consensus"; manual: "manual"; }>; wasRetried: z.ZodOptional; triageAction: z.ZodOptional; routingStage: z.ZodOptional; retryCount: z.ZodOptional; vendor: z.ZodOptional; family: z.ZodOptional; voterRole: z.ZodOptional; baselineId: z.ZodOptional; traceId: z.ZodOptional; requestId: z.ZodOptional; }, z.core.$strip>; /** Schema for filtering outcomes. */ declare const OutcomeQuerySchema: z.ZodObject<{ cli: z.ZodOptional, z.ZodEnum<{ "api:anthropic": "api:anthropic"; "api:google": "api:google"; "api:openai": "api:openai"; "api:custom-openai": "api:custom-openai"; }>, z.ZodLiteral<"unknown">]>>; category: z.ZodOptional>; source: z.ZodOptional>; success: z.ZodOptional; failureCategory: z.ZodOptional>; since: z.ZodOptional; limit: z.ZodOptional; excludeQualitySignals: z.ZodOptional>; baselineId: z.ZodOptional; }, z.core.$strip>; /** A single recorded task execution outcome. */ type TaskOutcome$1 = z.infer; /** Filter for querying stored outcomes. */ type OutcomeQuery = z.infer; /** Category of failure for failed outcomes (Issue #1025). */ type OutcomeFailureCategory = z.infer; /** * Extracts a classifiable message string from a non-Error value. * Returns undefined if the value is truly unclassifiable (#1466). */ declare function extractNonErrorMessage(error: unknown): string | undefined; /** Classifies an error into an OutcomeFailureCategory for recording. */ declare function categorizeOutcomeError(error: unknown): OutcomeFailureCategory; /** Classifies an error message string into an OutcomeFailureCategory. */ declare function categorizeOutcomeErrorMessage(msg: string): OutcomeFailureCategory; /** Aggregated stats for a group of outcomes. */ interface GroupStats { readonly count: number; readonly successRate: number; readonly avgDurationMs: number; } /** Aggregated performance summary from recorded outcomes. */ interface PerformanceSummary { readonly totalTasks: number; readonly successRate: number; readonly avgDurationMs: number; readonly byCli: ReadonlyMap; readonly byCategory: ReadonlyMap; } /** * nexus-agents/mcp - Structured Tool Error Envelope * * Caller-facing error contract for MCP tools. Replaces the opaque * `{ isError: true, content: [{ text }] }` string shape with a structured * envelope so callers (other tools, voter panels, the Claude/Codex/Gemini/ * OpenCode harnesses) can reason about retry-safety and recovery path * instead of string-matching arbitrary text. * * SCOPE — this envelope is caller-facing ONLY. The routing/circuit-breaker * layer classifies adapter subprocess failures through its own * `categorizeOutcomeError()` path (orchestration/outcomes/outcome-types.ts) * and never reads this envelope. `coarsenFailureCategory()` is a one-way * convenience for the rare tool that internally catches an * `OutcomeFailureCategory`-classified error and wants to surface it to its * caller — it is not, and must not become, a routing input. The two * taxonomies serve different layers; this is the single authoritative * projection between them. * * @module mcp/error-envelope * @see Issue #2649 */ /** * Caller-facing error category. Deliberately coarser than the routing * layer's 11-value `OutcomeFailureCategory` — a tool's caller only needs * enough resolution to choose a recovery path: * * - `transient` — network blip, rate limit, timeout. Retry is safe. * - `validation` — input shape/values wrong. Caller must fix its args. * - `permission` — auth / authorization / sandbox / access-policy denial. * - `business` — domain-logic refusal (dedup hit, precondition not met). * An expected, non-bug outcome — not a failure to retry. * - `internal` — unexpected, bug-class. Not retry-class; escalate. */ declare const ErrorCategorySchema: z.ZodEnum<{ validation: "validation"; internal: "internal"; transient: "transient"; permission: "permission"; business: "business"; }>; type ErrorCategory = z.infer; /** * nexus-agents/mcp - Tool Result Helpers * * Canonical type and factory functions for MCP tool results. * Extracted from index.ts to allow tool implementations to import * without circular dependencies. * * @module mcp/tools/tool-result */ /** * Common dependency interface shared by all MCP tool handlers. * * Tool-specific deps interfaces should extend this base. * (Source: Issue #1439 — DRY extraction of 25 duplicated Deps interfaces) */ interface BaseMcpToolDeps { /** Optional logger */ logger?: ILogger; /** Rate limiter for throttling tool calls (required) */ rateLimiter: RateLimiter$1; /** Security configuration (includes timeout settings) */ security?: SecurityConfig | undefined; } /** * MCP tool content types. */ interface TextContent { type: 'text'; text: string; } /** * MCP tool result. * * Uses mutable properties for compatibility with secure-handler * sanitization (which rewrites `text` in-place). */ interface ToolResult$1 { content: Array; isError?: boolean; /** Structured output for SDK outputSchema validation (Issue #1117) */ structuredContent?: Record; /** * Out-of-band metadata, never validated against `outputSchema`. The * structured error envelope (#2649) is carried here under * `ERROR_ENVELOPE_META_KEY`. */ _meta?: Record; } /** * Creates a successful tool result. * * @param text - The result text * @returns A ToolResult with the text content * * @example * ```typescript * return toolSuccess(JSON.stringify({ status: 'ok', data: result })); * ``` */ declare function toolSuccess(text: string): ToolResult$1; /** * Creates a successful tool result with structured content for outputSchema validation. * * When a tool is registered with outputSchema, the SDK validates structuredContent * against the schema. This helper returns both text (for display) and structured data. * * @param data - The structured result data (must match the tool's outputSchema) * @returns A ToolResult with both text content and structuredContent * * @example * ```typescript * return toolSuccessStructured({ experts: [...], count: 10 }); * ``` */ declare function toolSuccessStructured(data: Record): ToolResult$1; /** * Creates an error tool result. * * Back-compat alias for {@link toolStructuredError} — maps to the * conservative `internal` / non-retryable envelope. New code should call * `toolStructuredError` directly with the correct category; this alias * exists so the ~64 legacy call sites keep working during the #2649 * migration sweep. * * @param message - The error message * @returns A ToolResult with isError set to true and an `internal` envelope */ declare function toolError(message: string): ToolResult$1; /** * nexus-agents/mcp - Research Discover Tool * * MCP tool for discovering new research papers and repos from external sources. * Searches arXiv, GitHub, and other sources for relevant research. * * @module mcp/tools/research-discover * (Source: Research System Enhancement - Phase 1C) */ /** A discovered research item. */ interface DiscoveredItem { /** Source type */ source: string; /** Item title */ title: string; /** URL to the item */ url: string; /** Brief description */ description: string; /** Whether this item already exists in the registry */ alreadyInRegistry: boolean; /** Discovery date */ discoveredAt: string; /** Relevance score (0-1) relative to the search topic */ relevanceScore?: number; } /** * Input schema for research_discover tool. */ declare const ResearchDiscoverInputSchema: z.ZodObject<{ topic: z.ZodString; source: z.ZodDefault>>; maxResults: z.ZodDefault>; sinceDate: z.ZodOptional; relevanceThreshold: z.ZodDefault>; }, z.core.$strip>; /** * Type for validated research discover input. */ type ResearchDiscoverInput = z.infer; /** * Dependencies for research_discover tool. */ type ResearchDiscoverDeps = BaseMcpToolDeps; /** * Response from research_discover tool. */ interface ResearchDiscoverResponse { /** Topic that was searched */ topic: string; /** Sources queried */ sourcesQueried: string[]; /** Sources that failed during discovery */ failedSources: string[]; /** Discovered items */ items: DiscoveredItem[]; /** Total items found (before filtering) */ totalFound: number; /** * Items already in registry (filtered out). * * Meaningful ONLY when `registryConsulted` is true. When the registry could * not be read this is 0 because nothing could be matched, not because nothing * matched. */ alreadyInRegistry: number; /** * Whether the papers registry was actually read (#5925). * * `false` means the dedup pass did not run: every item is reported as new * regardless of what the registry holds. Required rather than optional so * every construction site has to answer, and so a caller cannot silently * inherit a default. */ registryConsulted: boolean; /** New items not yet in registry */ newItems: number; /** Items filtered out by relevance threshold */ filteredByRelevance: number; } /** * Registers the research_discover tool with the MCP server. * * @category MCP * @param server - MCP server instance * @param deps - Tool dependencies */ declare function registerResearchDiscoverTool(server: McpServer, deps: ResearchDiscoverDeps): void; /** * Structured ResearchContext — the research stage's output, captured directly * from the research tools instead of LLM-serialized to bare text (#3372). * * Per the 7/7 higher_order vote (Option A): the dev-pipeline research stage calls * `executeDiscovery` + the analyze path DIRECTLY for structured data, builds the * metadata here, and DERIVES the human-readable `text` deterministically from that * same structure — a single source of truth, so the text voters read and the * maturity signals downstream consumers (plan/vote, #3372 increment 2) weight on * can never diverge. No LLM in this path. * * Security (vote condition): discovered titles + recommendations are EXTERNAL, * untrusted content — they are escaped (backticks/control chars neutralized, * newlines collapsed) and the rendered list is bounded before being embedded in a * prompt. The full item set is preserved in `metadata` for programmatic consumers; * only the rendered `text` is truncated. * * @module pipeline/research-context */ /** A discovered research item, projected to the fields downstream consumers use. */ interface ResearchDiscoveredItem { readonly title: string; readonly url: string; readonly relevanceScore?: number; readonly alreadyInRegistry: boolean; } /** Coarse maturity signals voters can weight on (#3372). */ interface ResearchQualitySignals { readonly totalFound: number; readonly newItems: number; readonly alreadyInRegistry: number; } /** Structured research metadata — the part that was previously lost to text. */ interface ResearchContextMetadata { readonly discoveredItems: readonly ResearchDiscoveredItem[]; readonly recommendations: readonly string[]; readonly qualitySignals: ResearchQualitySignals; } /** The research stage's output: derived text + the structure it was derived from. */ interface ResearchContext { readonly text: string; readonly metadata: ResearchContextMetadata; } /** Coarse research-maturity bucket for the #3234 measurement surface. */ type ResearchMaturityBucket = 'none' | 'low' | 'high'; /** Per-bucket aggregate for the research-maturity measurement report (#3234). */ interface ResearchMaturityBucketStats { /** Number of records (patterns) in this bucket. */ readonly count: number; /** Total attempts across the bucket's records (the successRate denominator). */ readonly attempts: number; /** Attempt-weighted success rate `[0,1]` (0 when there are no attempts). */ readonly successRate: number; } /** * The #3234 measurement surface output: success-rate by research-maturity bucket. * This is the NAMED CONSUMER that makes the recorded `researchMaturity` non- * speculative — it does NOT influence routing (that is gated on a measured lift, * #3815). v1 LIMITATION: the buckets are not yet controlled for task-vector * similarity, so a positive `highVsNoneDelta` is suggestive, not causal (it may * partly re-measure topic). Use it to decide whether to pursue #3815, not to act. */ interface ResearchMaturityReport { readonly byBucket: Readonly>; /** `high.successRate − none.successRate`; 0 when either bucket is empty. */ readonly highVsNoneDelta: number; readonly totalRecords: number; } /** * nexus-agents/context - Routing Memory Bridge * * Bridges MobiMem's three modules (Profile, Experience, Action) with * the model routing system to enable learned routing based on history. * * @module context/routing-memory * @see Issue #461 - Implement routing memory bridge * @see Issue #148 - Preference-Trained Routing * @see Issue #149 - MobiMem Post-Deployment Evolution (arXiv:2512.15784) */ /** * Performance metrics for a model on a task type. */ interface ModelPerformance { /** Average quality score (0-1) */ readonly avgQuality: number; /** Success rate (0-1) */ readonly successRate: number; /** Average latency in milliseconds */ readonly avgLatencyMs: number; /** Average tokens used */ readonly avgTokens: number; /** Number of observations */ readonly observations: number; } /** * Model preference with performance context. */ interface ModelPreference$1 { /** Model/CLI name */ readonly model: CliName; /** Preference strength (0-1) */ readonly strength: number; /** Historical performance */ readonly performance: ModelPerformance; /** Confidence in this preference */ readonly confidence: number; } /** * Experience pattern for workflow execution. */ interface ExperiencePattern { /** Workflow or task type */ readonly workflow: string; /** Sequence of models used */ readonly modelSequence: readonly CliName[]; /** Success rate for this pattern */ readonly successRate: number; /** Average total duration */ readonly avgDurationMs: number; /** How often this pattern was used */ readonly usageCount: number; } /** * Cached action result. */ interface CachedActionResult { /** Action signature/hash */ readonly action: string; /** Cached result */ readonly result: unknown; /** Model that produced the result */ readonly model: CliName; /** When cached */ readonly cachedAt: Date; /** Time saved by using cache (ms) */ readonly timeSavedMs: number; } /** * Configuration for routing memory. */ interface RoutingMemoryConfig { /** Minimum observations before considering preference */ readonly minObservations: number; /** Confidence threshold for preferences */ readonly confidenceThreshold: number; /** Success rate threshold for experience patterns */ readonly successRateThreshold: number; /** Maximum age for cached actions (ms) */ readonly actionCacheMaxAgeMs: number; /** Logger instance */ readonly logger?: ILogger; } /** * Interface for routing memory operations. */ interface IRoutingMemory { /** Store model preference for a task type */ storePreference(model: CliName, taskType: string, performance: ModelPerformance): void; /** Get preferences for a task type */ getPreferences(taskType: string): readonly ModelPreference$1[]; /** Record workflow execution experience */ recordExperience(workflow: string, models: readonly CliName[], success: boolean, metrics: { durationMs: number; tokensUsed: number; qualityScore?: number; /** #3234: research-maturity [0,1] of the run, recorded for measurement. */ researchMaturity?: number; }): void; /** Get experience patterns for a workflow type */ getExperiencePatterns(workflow: string): readonly ExperiencePattern[]; /** * #3234 measurement surface: success-rate by research-maturity bucket across all * recorded experience. Read-only — does NOT influence routing (gated → #3815). */ getResearchMaturityReport(): ResearchMaturityReport; /** Cache an action result */ cacheAction(action: string, model: CliName, result: unknown, durationMs: number): void; /** Get cached action result if available */ getCachedAction(action: string): CachedActionResult | undefined; /** Get routing recommendation based on history */ getRecommendation(taskType: string): CliName | undefined; /** Get statistics */ getStats(): RoutingMemoryStats; } /** * Statistics for routing memory. */ interface RoutingMemoryStats { readonly totalPreferences: number; readonly totalExperiences: number; readonly cacheHits: number; readonly cacheMisses: number; readonly recommendationsMade: number; } /** * nexus-agents/cli-adapters - Preference Router Types * * Type definitions for preference-trained routing (RouteLLM pattern). * Uses human preference data to learn routing decisions. * * @module cli-adapters/preference-router-types * (Source: Issue #148, arXiv:2406.18665) */ /** * A single preference data point comparing model outputs. */ interface PreferenceDataPoint { /** Unique identifier */ readonly id: string; /** The input query */ readonly query: string; /** Extracted query features */ readonly features: QueryFeatures; /** Whether the strong model was preferred */ readonly strongModelPreferred: boolean; /** Optional: actual strong model response quality score */ readonly strongModelQuality?: number | undefined; /** Optional: actual weak model response quality score */ readonly weakModelQuality?: number | undefined; /** When this preference was recorded */ readonly recordedAt: Date; /** Domain or task category */ readonly domain?: string | undefined; } /** * Features extracted from a query for preference prediction. */ interface QueryFeatures { /** Query length in tokens (estimated) */ readonly tokenCount: number; /** Complexity score (0-1) */ readonly complexity: number; /** Whether query requires reasoning */ readonly requiresReasoning: boolean; /** Whether query requires code generation */ readonly requiresCode: boolean; /** Whether query requires creativity */ readonly requiresCreativity: boolean; /** Whether query has ambiguity */ readonly hasAmbiguity: boolean; /** Domain category */ readonly domain: string; /** Keywords present (hashed for privacy) */ readonly keywordSignature: string; } /** * Result of a preference prediction. */ interface PreferencePrediction { /** Probability that strong model is significantly better */ readonly strongModelProbability: number; /** Confidence in this prediction (0-1) */ readonly confidence: number; /** Features used for prediction */ readonly features: QueryFeatures; /** Number of similar data points used */ readonly supportingDataPoints: number; } /** * Routing decision based on preference prediction. */ interface PreferenceRoutingDecision { /** Selected model tier */ readonly selectedTier: 'strong' | 'weak'; /** Selected adapter */ readonly selectedCli: CliName; /** Preference prediction details */ readonly prediction: PreferencePrediction; /** Reason for selection */ readonly reason: string; /** Routing decision time in ms */ readonly routingLatencyMs: number; /** Cost savings compared to always using strong model */ readonly estimatedCostSavings: number; } /** * Model tier configuration. */ interface ModelTier { /** Tier name */ readonly tier: 'strong' | 'weak'; /** CLI adapter name */ readonly cli: CliName; /** Cost per 1M tokens (input + output averaged) */ readonly costPerMillionTokens: number; /** Quality baseline (0-1) */ readonly qualityBaseline: number; } /** * Preference router configuration. */ interface PreferenceRouterConfig { /** Strong model configuration */ readonly strongModel: ModelTier; /** Weak model configuration */ readonly weakModel: ModelTier; /** Threshold for routing to strong model (0-1) */ readonly routingThreshold: number; /** Minimum data points before using learned routing */ readonly minDataPoints: number; /** Maximum data points to store */ readonly maxDataPoints: number; /** Whether to enable online learning */ readonly enableOnlineLearning: boolean; /** Domain-specific threshold overrides */ readonly domainThresholds?: Record | undefined; } /** * Default preference router configuration. */ declare const DEFAULT_PREFERENCE_ROUTER_CONFIG: PreferenceRouterConfig; /** * Zod schema for config validation. */ declare const PreferenceRouterConfigSchema: z.ZodObject<{ strongModel: z.ZodObject<{ tier: z.ZodLiteral<"strong">; cli: z.ZodEnum<{ claude: "claude"; gemini: "gemini"; codex: "codex"; opencode: "opencode"; }>; costPerMillionTokens: z.ZodNumber; qualityBaseline: z.ZodNumber; }, z.core.$strip>; weakModel: z.ZodObject<{ tier: z.ZodLiteral<"weak">; cli: z.ZodEnum<{ claude: "claude"; gemini: "gemini"; codex: "codex"; opencode: "opencode"; }>; costPerMillionTokens: z.ZodNumber; qualityBaseline: z.ZodNumber; }, z.core.$strip>; routingThreshold: z.ZodDefault; minDataPoints: z.ZodDefault; maxDataPoints: z.ZodDefault; enableOnlineLearning: z.ZodDefault; domainThresholds: z.ZodOptional>; }, z.core.$strip>; /** * Statistics about the preference router's learned model. */ interface PreferenceModelStats { /** Total data points collected */ readonly totalDataPoints: number; /** Data points by domain */ readonly dataPointsByDomain: Record; /** Average strong model preference rate */ readonly strongModelPreferenceRate: number; /** Routing accuracy (if validation data available) */ readonly routingAccuracy?: number; /** Estimated cost savings rate */ readonly estimatedCostSavingsRate: number; /** Last updated timestamp */ readonly lastUpdatedAt: Date; } /** * Interface for the preference data store. */ interface IPreferenceDataStore { /** Store a new preference data point */ store(dataPoint: PreferenceDataPoint): void; /** Get all data points */ getAll(): readonly PreferenceDataPoint[]; /** Get data points by domain */ getByDomain(domain: string): readonly PreferenceDataPoint[]; /** Find similar data points based on features */ findSimilar(features: QueryFeatures, limit: number): readonly PreferenceDataPoint[]; /** Get statistics */ getStats(): PreferenceModelStats; /** Clear all data */ clear(): void; } /** * Routing Metrics Types * * Type definitions for routing metrics collection and visualization. * Extracted to break circular dependency between routing-metrics.ts * and routing-metrics-helpers.ts. * * @module observability/routing-metrics-types * (Source: Alignment Roadmap Phase 1, Issue #171) * (Source: Issue #392 - Circular dependency resolution) */ /** Individual routing decision record. */ interface RoutingRecord { readonly timestamp: string; readonly traceId: string; readonly selectedModel: CliName; readonly alternativeModels: readonly CliName[]; readonly isExploration: boolean; readonly taskType?: string; readonly contextTokens?: number; /** Time taken to make the routing decision (ms). */ readonly routingLatencyMs?: number; } /** Outcome record for a routing decision. */ interface OutcomeRecord { readonly timestamp: string; readonly traceId: string; readonly model: CliName; readonly success: boolean; readonly reward: number; readonly qualityScore?: number; readonly latencyMs?: number; } /** Aggregated metrics for a single model. */ interface ModelMetrics { readonly model: CliName; readonly selectionCount: number; readonly selectionPercent: number; readonly avgReward: number; readonly avgQuality: number; readonly avgLatencyMs: number; readonly successRate: number; readonly explorationCount: number; } /** Overall routing metrics. */ interface RoutingMetrics { readonly periodStart: string; readonly periodEnd: string; readonly totalDecisions: number; readonly totalOutcomes: number; readonly modelMetrics: readonly ModelMetrics[]; readonly explorationRate: number; readonly avgReward: number; readonly avgRewardTrend: number; readonly avgRoutingLatencyMs: number; } /** Dashboard rendering configuration. */ interface DashboardConfig$1 { readonly width: number; readonly showTrends: boolean; readonly periodHours: number; } /** * Confidence Cascade Stage * * Routes based on task complexity and model confidence profiles. * Simpler tasks can use faster/cheaper models; complex tasks escalate. * * @module cli-adapters/routing/stages/confidence-cascade-stage * (Source: ADR-0005, Issue #99, arXiv:2510.05164 - SATER pattern) */ /** * Configuration for the confidence cascade stage. */ interface ConfidenceCascadeConfig { /** Threshold for escalating to more capable model */ readonly escalationThreshold: number; /** Weight for complexity-based scoring */ readonly complexityWeight: number; /** Enable debug logging */ readonly debug: boolean; } /** * Capability Match Stage * * Scores candidates based on capability profile matching to task requirements. * Uses weighted multi-criteria scoring based on task type. * * @module cli-adapters/routing/stages/capability-match-stage * (Source: ADR-0005, arXiv:2508.21141 - PILOT pattern) */ /** * Task type categories for capability matching. */ type TaskType$1 = 'reasoning' | 'code' | 'creative' | 'general'; /** * Capability weights by dimension. */ interface CapabilityWeights { readonly reasoning: number; readonly codeGeneration: number; readonly speed: number; readonly costEfficiency: number; } /** * Cross-attention matrix: for each task feature, weights each capability dimension. * Entry [feature][capability] = attention weight (how important capability is for feature). * Rows sum to 1.0 (softmax-normalized). Each row is a CapabilityWeights. * * This implements a simplified cross-attention mechanism (arXiv:2508.21141 PILOT) * where task features attend to model capabilities via learned/configured weights. */ type AttentionMatrix = Record; /** * Configuration for the capability match stage. */ interface CapabilityMatchConfig { /** Weight for capability scoring in overall score */ readonly capabilityWeight: number; /** Bonus for task-type specialization */ readonly specializationBonus: number; /** Enable debug logging */ readonly debug: boolean; /** Custom attention matrix (overrides default cross-attention weights) */ readonly attention?: AttentionMatrix; } /** * Quality Constraint Stage * * Applies quality constraints to filter candidates that don't meet * minimum quality, cost, or latency requirements. * * @module cli-adapters/routing/stages/quality-constraint-stage * (Source: ADR-0005, arXiv:2508.21141 - PILOT pattern) */ /** * Configuration for the quality constraint stage. */ interface QualityConstraintConfig { /** Minimum quality score (0-1) */ readonly minQuality: number; /** Maximum cost per task in USD */ readonly maxCostUsd: number; /** Maximum latency in milliseconds */ readonly maxLatencyMs: number; /** Expected tokens for cost estimation */ readonly expectedTokens: number; /** * Expected INPUT tokens, when the caller knows the split. Supplying both this * and {@link expectedOutputTokens} prices the ceiling exactly; leaving them * unset prices {@link expectedTokens} at the OUTPUT rate, which is the * conservative bound (#5186). */ readonly expectedInputTokens?: number | undefined; /** Expected OUTPUT tokens, when the caller knows the split. */ readonly expectedOutputTokens?: number | undefined; /** Allow fallback to highest quality if all filtered */ readonly allowFallback: boolean; } /** * Resource Strategy Stage * * Implements resource-aware strategy oscillation for the routing pipeline. * Dynamically adjusts model scoring based on budget utilization level, * oscillating between aggressive (prefer quality) and conservative (prefer cost) * strategies as resources deplete. * * @module cli-adapters/routing/stages/resource-strategy-stage * (Source: Issue #998 — Resource-aware strategy oscillation in routing pipeline) */ /** * Configuration for the resource strategy stage. */ interface ResourceStrategyConfig { /** Threshold above which aggressive tier activates (0-1) */ readonly aggressiveThreshold: number; /** Threshold above which balanced tier activates (0-1) */ readonly balancedThreshold: number; /** Threshold above which conservative tier activates (0-1) */ readonly conservativeThreshold: number; /** Score boost for quality-oriented CLIs in aggressive mode */ readonly aggressiveBoost: number; /** Score boost for cost-efficient CLIs in conservative mode */ readonly conservativeBoost: number; /** Score boost for cheapest CLI in critical mode */ readonly criticalBoost: number; } /** * nexus-agents/core - Model Adapter Types * * Unified interface for all model adapters (Claude, OpenAI, Gemini, Ollama). */ /** * Model capabilities supported by adapters. */ declare const ModelCapability: { readonly COMPLETION: "completion"; readonly STREAMING: "streaming"; readonly TOOL_USE: "tool_use"; readonly VISION: "vision"; readonly EXTENDED_THINKING: "extended_thinking"; }; type ModelCapability = (typeof ModelCapability)[keyof typeof ModelCapability]; /** * Message role in a conversation. */ type MessageRole = 'user' | 'assistant' | 'system'; /** * Content block types in messages and responses. */ type ContentBlock = { type: 'text'; text: string; } | { type: 'tool_use'; id: string; name: string; input: unknown; } | { type: 'tool_result'; tool_use_id: string; content: string; is_error?: boolean; } | { type: 'image'; source: { type: 'base64'; media_type: string; data: string; }; }; /** * Message in a conversation. */ interface Message { role: MessageRole; content: string | ContentBlock[]; } /** * Tool definition for function calling. */ interface ToolDefinition { name: string; description: string; inputSchema: Record; } /** * Response format specification. * * @remarks * Adapter support (Issue #470): * - **OpenAI**: Full support for `json_object` and `json_schema` * - **Ollama**: Supports `json_object` and `json_schema` (passes schema directly) * - **Claude**: NOT SUPPORTED - Anthropic API lacks native JSON mode * - **Gemini**: NOT SUPPORTED - Google API lacks JSON format constraints * * For Claude/Gemini, use tool use or prompt engineering for structured output. */ type ResponseFormat = { type: 'text'; } | { type: 'json_object'; } | { type: 'json_schema'; schema: Record; }; /** * Request to complete a conversation. */ interface CompletionRequest { /** Conversation messages */ messages: Message[]; /** System prompt (if not included in messages) */ systemPrompt?: string; /** Sampling temperature (0.0 - 1.0) */ temperature?: number; /** Maximum tokens to generate */ maxTokens?: number; /** * Per-request timeout override in milliseconds. When set, adapters that * support it use this instead of their construction-time default — lets a * long-running caller (e.g. a consensus vote with a 300s budget) prevent the * adapter's shorter standard timeout from firing first (#3304). Adapters that * don't support per-request timeouts ignore it. */ timeoutMs?: number; /** Working directory for CLI adapters; API adapters ignore this field. */ workDir?: string; /** Tools available for the model */ tools?: ToolDefinition[]; /** * Expected response format. * * @remarks * Only supported by OpenAI and Ollama adapters. Claude and Gemini * adapters will ignore this field. See {@link ResponseFormat} for details. */ responseFormat?: ResponseFormat; /** Stop sequences */ stop?: string[]; /** * Cancellation signal (#3036). When the signal aborts, the adapter * cancels the in-flight model call. All five concrete adapters * (claude, openai, ollama, gemini, openai-compat) honor this by * passing the signal to their respective vendor SDK. * * Used by `withWatchdog` to cancel race-loser model calls when the * worker-dispatch timeout wins. Without this, the SDK keeps running * after `Promise.race` resolves with the timeout — late results land * in OutcomeStore for a decision already discarded. * * Typed as `AbortSignal | undefined` (not `AbortSignal?`) so adapter * internals that destructure `request` keep working under * `exactOptionalPropertyTypes`. */ signal?: AbortSignal | undefined; } /** * Token usage statistics. */ interface TokenUsage { inputTokens: number; outputTokens: number; totalTokens: number; /** * Whether `inputTokens` is a measurement (#4835). * * `false` means the vendor did not report a prompt count on this event, so * `inputTokens` is a placeholder `0` — and `totalTokens` is therefore a * LOWER BOUND, not a total. A stream consumer that bills on these numbers * otherwise prices a large-context call at zero prompt cost, which * under-counts in the dangerous direction. * * Absent means measured, so no existing producer changes meaning. Where * NOTHING is known, prefer omitting `usage` entirely — that is the #4439 * policy, and the field is already optional on the chunk. */ inputTokensMeasured?: boolean; /** * Input tokens READ from an existing prompt cache, when the vendor reports * them separately. Billed at roughly a tenth of the uncached input rate, so * kept out of `inputTokens` rather than summed into it (#4435). */ cachedInputTokens?: number; /** * Input tokens spent WRITING the cache. Billed at roughly 1.25x the uncached * rate — the opposite end from a cache read, which is why the two stay * separate (#4438). */ cacheCreationInputTokens?: number; } /** * Reason the model stopped generating. */ type StopReason = 'end_turn' | 'max_tokens' | 'stop_sequence' | 'tool_use'; /** * Response from a completion request. */ interface CompletionResponse { /** Response content blocks */ content: ContentBlock[]; /** * Token usage statistics, when the vendor reported them. * * OPTIONAL on purpose (#4439). Producers used to synthesise `0/0/0` from an * absent vendor report, which is indistinguishable downstream from a real * zero-token call — that fabrication silently defeated the measured-voter * gate (#4436) on every live path. Absence must stay absent; consumers that * need a number should treat `undefined` as "unknown", never as zero. */ usage?: TokenUsage; /** Reason generation stopped */ stopReason: StopReason; /** Model that generated the response */ model: string; /** * Stderr the CLI transport captured while serving this completion, when the * adapter is a CLI bridge and the pipe was non-empty (#6094). A sandboxed * shell failure inside the CLI's own tool loop lands here while the model * still returns a parsed answer; the voter classifier reads it as the * structured "could not read the artifact" signal. Absent for API adapters * and for a clean run — never an empty string. */ cliStderr?: string; /** * The model the caller asked for, when a CLI bridge answered with a different * one from the same family (#6120): the claude adapter substitutes the next * registry alias after an out-of-credits envelope. Present only on a * substituted response, so the voter path can disclose which model actually * voted (#6115). Absent means the requested model answered. */ fallbackFrom?: string; /** * Request params the adapter dropped before sending (#4069, epic #4066 layer 3). * Present (and non-empty) only when a param was silently unsupported — e.g. a * post-Opus-4.6 Claude or OpenAI reasoning model that rejects `temperature`. The * request still ran (at the provider default); this surfaces what was omitted so * the caller can SEE a behavioral param had no effect. Absent when nothing was * dropped. Typed via the adapter-layer {@link DroppedParam} shape, re-declared * structurally here to avoid a core→adapters import cycle. */ warnings?: readonly { readonly param: string; readonly reason: string; readonly severity: 'behavioral' | 'cosmetic'; }[]; } /** * Chunk from a streaming response. */ type StreamChunk = { type: 'content_block_start'; index: number; contentBlock: ContentBlock; } | { type: 'content_block_delta'; index: number; delta: { type: 'text_delta'; text: string; }; } | { type: 'content_block_stop'; index: number; } | { type: 'message_start'; message: { model: string; }; usage?: TokenUsage; } | { type: 'message_delta'; delta: { stop_reason: StopReason; }; usage?: TokenUsage; } | { type: 'message_stop'; }; /** * Unified interface for all model adapters. */ interface IModelAdapter { /** Provider identifier (e.g., 'anthropic', 'openai') */ readonly providerId: string; /** Model identifier (e.g., 'claude-sonnet-4', 'gpt-4o') */ readonly modelId: string; /** Capabilities this model supports */ readonly capabilities: readonly ModelCapability[]; /** * Send a completion request. * @param request - The completion request * @returns Result with response or ModelError */ complete(request: CompletionRequest): Promise>; /** * Stream a completion request. * @param request - The completion request * @yields StreamChunk objects as they arrive */ stream(request: CompletionRequest): AsyncIterable; /** * Count tokens in text. * @param text - Text to count tokens for * @returns Approximate token count */ countTokens(text: string): Promise; /** * Validate adapter configuration. * @returns Ok if valid, ConfigError if invalid */ validateConfig(): Result; /** * (Optional, #2529) List models served by this adapter's endpoint. * * Implemented by adapters facing OpenAI-compatible endpoints (the * upstream OpenAI API, OpenRouter, vLLM, custom gateways, etc.) — * usually wraps `GET /v1/models`. Result is the harness-side identity * resolver's most-trusted signal for "what model is actually being * served behind this adapter." * * Subprocess-CLI adapters (claude / codex / gemini / opencode) leave * this undefined; identity for those falls back to `modelId` parse. * * Implementations should cache the result for ~5 minutes — operators * shouldn't pay round-trip latency on every resolve. Failures * (network error, endpoint unsupported, auth missing) should throw * so the caller can fall back; do NOT silently return an empty list. */ listModels?(): Promise; } /** * Metadata for one model served by an OpenAI-compatible endpoint * (#2529). Mirrors the shape of `GET /v1/models`. Most fields are * optional because gateways differ in what they expose. */ interface ModelMetadata { /** Stable model id — matches what callers pass as `modelId` to `complete`. */ readonly id: string; /** Free-form vendor / org tag. Upstream OpenAI: `openai`/`system`. OpenRouter: `anthropic`/`google`/etc. */ readonly ownedBy?: string; /** Unix epoch seconds when the model was created (when the gateway reports it). */ readonly createdAt?: number; /** Free-form capability strings the gateway exposes — passthrough, no normalisation. */ readonly capabilities?: readonly string[]; /** Maximum context window in tokens — populated by gateways that report it (OpenRouter does). */ readonly contextLength?: number; /** Pricing — passthrough only. Gateway-defined units. */ readonly pricing?: { readonly input?: number; readonly output?: number; }; } /** * Dynamic model-identity resolver (#2529). * * Real-world `modelId` strings are messy: * - clean upstream: `claude-sonnet-4-6`, `gpt-4o`, `gemini-2.0-flash` * - vendor-prefixed: `anthropic/claude-sonnet-4-6`, `meta-llama/llama-3.3-70b` * - dated: `claude-3-5-sonnet-20241022`, `gpt-4o-2024-08-06` * - operator-renamed: `2025-claude-opus-4_0_high`, `workspace-claude-prod` * - opaque: `internal-fast-model` * * This module turns any of those into a `ResolvedModelIdentity` — * vendor + family + version + capability hints — so the * agentic-adapter layer can pick a behaviour profile based on the * actual served model, NOT on `IModelAdapter.providerId` (which for a * custom OpenAI gateway is always `openai` regardless of what model * the gateway is fronting). * * Resolution priority (highest first): * 1. operator `modelHints` — explicit override at construction * 2. probe of `IModelAdapter.listModels()` — `owned_by` field * 3. modelId-string parse — fuzzy regex table on the normalised id * 4. `unknown` defaults * * Each layer fills only the fields its higher-priority neighbour left * blank, so an operator can hint `{ vendor: 'anthropic' }` and still * let `family` come from the probe / parse. * * @module config/model-identity */ /** Coarse vendor bucket — drives behaviour-profile lookup downstream. */ type ModelVendor = 'anthropic' | 'openai' | 'google' | 'meta' | 'qwen' | 'nvidia' | 'mistral' | 'cohere' | 'deepseek' | 'unknown'; /** * Family inside a vendor — `claude-opus`, `claude-sonnet`, `gpt-4o`, * `gemini-flash`, `llama-3`, etc. `unknown` when we recognised the * vendor but not the specific family (e.g., gateway-renamed model). */ type ModelFamily = string; /** Where each piece of the resolved identity came from — useful for audit logs. */ type IdentitySource = 'modelHints' | 'probe' | 'modelIdParse' | 'default'; /** * Resolved identity for a served model. Returned by `resolveModelIdentity`. * * The `quirks` array carries free-form capability hints lifted from * the modelId string — `'embedding'` to flag non-chat models, * `'thinking'` for reasoning variants, `'vision'`, `'mini'`, `'high'`, * etc. Behaviour profiles consult this to override their defaults. */ interface ResolvedModelIdentity { readonly vendor: ModelVendor; readonly family: ModelFamily; readonly version?: string; readonly quirks: readonly string[]; readonly source: IdentitySource; readonly rawModelId: string; } /** Operator-supplied identity overrides. Any field forces; others fall through. */ interface ModelHints { readonly vendor?: ModelVendor; readonly family?: ModelFamily; readonly version?: string; readonly quirks?: readonly string[]; } /** * Pattern-derivation logic for ModelRegistry — extracted from * `model-registry.ts` to break a runtime circular import with * `in-tree-entries.ts` (which needs `deriveEntry` to build the * in-tree slice for `buildDefaultRegistry()`). * * No state lives here; everything is pure. The `ModelEntry` type * is imported type-only from `model-registry.ts` to avoid a runtime * dependency cycle. * * @module config/model-derivation */ /** * Universal fallback. Used when nothing more specific matches — * unknown vendor + family + no probe data. Safe defaults. */ declare const DEFAULT_ENTRY: Omit; /** * Build an entry from vendor + family + quirks when no authoritative * row matches. Source stamped `'derived'`; capability fields left * undefined (derived entries don't have measured pricing/quality data). */ declare function deriveEntry(modelId: string, identity: ResolvedModelIdentity): ModelEntry; /** * Unified ModelRegistry (#2540). * * Single source of truth for per-model metadata. Replaces the previous * split between: * - `model-capabilities.ts` (canonical hardcoded list; renamed to * `in-tree-data.ts` in #2546 slice E, helpers moved here + into * `model-config-helpers.ts`) * - `model-behavior-profile.ts` (vendor-pattern-matched runtime * behaviour; file deleted in #2540 PR 2) * * Each `ModelEntry` carries BOTH capability and behaviour fields. The * registry's `getEntry()` always returns something — exact match if * the modelId is known, derived entry if vendor + family can be * inferred, universal default otherwise. * * Resolution chain (highest priority first; the constructor loads * lowest-priority first so higher tiers overwrite lower ones field-by-field — * see {@link EntrySource} and `ModelRegistry` constructor): * * 1. modelHints / explicit alias ← operator override (resolver hints) * 2. manifest entries ← operator manifest overlay (#2547) * 3. in-tree authoritative entries ← measured/validated by us * 4. models.dev snapshot ← seeded externally * 5. generated catalog (LiteLLM) ← LOWEST tier; long-tail breadth (#3293) * 6. derived from vendor + family ← pattern-matched fallback * 7. universal default ← never fails * * This module ships the type + class + derived-fallback logic. The * authoritative in-tree entries are populated by `buildInTreeEntries()`; the * models.dev snapshot is loaded by `loadModelsDevSnapshot()` in * `buildDefaultRegistry()`. * * Availability is a SEPARATE concern — see `AvailableModelsCache` * (`config/available-models-cache.ts`). The registry tells you "what does * this model id mean"; `AvailableModelsCache` tells you "is the harness * currently able to serve it." Routing decisions consume both. * * @module config/model-registry */ /** * Tool-definition format the model expects in `CompletionRequest.tools`. * Each `IModelAdapter` translates from the canonical `ToolDefinition` * shape to the provider's native form, so this field is informational * for routing/scoring, not request-side. */ type ToolDefinitionFormat = 'openai' | 'anthropic' | 'gemini'; /** * Prompt-caching opt-in level. `'ephemeral'` adds Anthropic-style * `cache_control` markers; other providers ignore the field. */ type PromptCachingMode = 'none' | 'ephemeral' | 'aggressive'; /** * Where this entry came from. Higher-priority sources override lower * ones field-by-field; `derived` is always the fallback floor. */ type EntrySource = 'in-tree' | 'models-dev' | 'manifest' | 'derived' | 'generated'; /** * How the normalized/identity resolution tier (#4164) found a canonical * entry for a decorated gateway model id: `'normalized'` — the id matched * an entry/alias after `normaliseModelId`; `'identity'` — the parsed * {vendor, family, version} matched exactly one loaded entry. */ type MatchedVia = 'normalized' | 'identity'; /** * One model's full metadata. Combines what was previously split * across `ModelCapability` (capability/pricing/quality) and * `ModelBehaviorProfile` (runtime behaviour toggles). * * All capability + pricing + quality fields are optional because * derived entries (vendor known but no authoritative data) won't * have them. Routing consumers must handle absence gracefully. * * Behaviour fields always have values (defaulted from vendor/family * profile if no exact entry exists). */ interface ModelEntry { /** Canonical id, e.g. `claude-opus-4-1`, `gpt-5.4`, `meta/llama-3-70b`. */ readonly id: string; /** * Alternate strings that should resolve to this entry. Operators * extend via the manifest (PR 4) when a gateway exposes a renamed * version of a known model. */ readonly aliases?: readonly string[]; /** Coarse vendor bucket — drives behaviour-profile fallback chains. */ readonly vendor: ModelVendor; /** Family inside a vendor — `claude-opus`, `gpt-4o`, `llama-3`. */ readonly family: string; /** Version string (best-effort; `4-1`, `2024-08-06`, etc). */ readonly version?: string; /** Human-readable display name for UI / logs. */ readonly displayName?: string; readonly contextWindow?: number; readonly maxOutputTokens?: number; readonly inputModalities?: readonly InputModality[]; readonly outputModalities?: readonly OutputModality[]; readonly toolCapabilities?: readonly ToolCapability[]; readonly specialFeatures?: readonly SpecialFeature[]; readonly pricing?: Pricing; readonly qualityScores?: QualityScores; readonly notes?: string; /** * Request parameters this model rejects (carried from * `ModelCapability.unsupportedParameters`, #4067). Consumed by * `model-parameter-support.ts`; absence means the regex fallback applies. */ readonly unsupportedParameters?: readonly string[]; /** * Max-tokens param name this model expects (carried from * `ModelCapability.maxTokensParam`, #4049/#4067). Absence defaults to * `'max_tokens'` (with the OpenAI-reasoning regex fallback). */ readonly maxTokensParam?: 'max_tokens' | 'max_completion_tokens'; /** Which CLI tool this model belongs to (e.g. 'claude', 'gemini'). */ readonly cliName?: string; /** Short alias the CLI accepts (e.g. 'opus' for claude). */ readonly cliAlias?: string; /** Vendor model id the CLI passes upstream (e.g. 'claude-opus-4-6'). */ readonly cliModelName?: string; readonly parallelToolCalls: boolean; readonly promptCaching: PromptCachingMode; readonly toolDefinitionFormat: ToolDefinitionFormat; readonly maxRecommendedTurnBudget: number; readonly strictJson: boolean; readonly quirks: readonly string[]; readonly profileId: string; readonly source: EntrySource; /** ISO date when this entry was last validated against the upstream. */ readonly verifiedAt?: string; /** * Set when the normalized/identity resolution tier (#4164) matched this * (decorated) id to a canonical entry. Absent for exact/alias hits and * pure derivation. */ readonly matchedVia?: MatchedVia; /** Canonical id of the matched entry the pricing/metadata came from. */ readonly resolvedFrom?: string; } interface ModelRegistryOptions { /** Authoritative in-tree entries. Highest priority. */ readonly inTreeEntries?: readonly ModelEntry[]; /** models.dev snapshot entries. Lower priority than in-tree. */ readonly modelsDevEntries?: readonly ModelEntry[]; /** Operator manifest entries. Higher priority than in-tree. */ readonly manifestEntries?: readonly ModelEntry[]; /** * Broad generated-catalog (LiteLLM) breadth entries. LOWEST priority — * overwritten by every other tier; provides long-tail coverage so unknown * models resolve to real catalog data instead of a bare derived default * (#3293, preserving the legacy CapabilityDiscovery T2 breadth). */ readonly generatedEntries?: readonly ModelEntry[]; } /** * The unified model-metadata registry. Construct once, share across * the process. `getEntry(modelId)` always returns something. */ declare class ModelRegistry { private readonly byId; private readonly byAlias; /** * `vendor|family|version` → candidate entries, for the identity tier * (#4164). Built ONCE, lazily on the first fuzzy lookup — the entry maps * are immutable after construction, so it never goes stale. No caching of * UNMATCHED ids happens anywhere (the index only holds loaded entries). */ private identityIndex; constructor(options?: ModelRegistryOptions); /** * Resolve a model id to its full metadata entry. Always returns — * unknown models get a derived entry with sensible defaults. * * On exact miss, the normalized/identity resolution tier (#4164) runs * BEFORE derivation so decorated gateway ids (`Claude_Opus_4.8_hardened`) * still pick up the canonical entry's pricing/metadata. */ getEntry(modelId: string, hints?: ModelHints): ModelEntry; /** * Has the registry got an authoritative entry for this id? * Consumers use this to distinguish "we know X" from "we guessed." */ hasAuthoritative(modelId: string): boolean; /** * All loaded entries across every tier (generated + models.dev + in-tree + * manifest), deduped by id (later sources overwrite earlier). This is NOT * filtered to authoritative entries — `models-dev`/`generated` are * catalog-breadth tiers; use `hasAuthoritative()` to tell them apart. */ allEntries(): readonly ModelEntry[]; /** Snapshot of canonical id → entry mapping. */ toMap(): ReadonlyMap; private lookupExact; /** * Normalized/identity resolution tier (#4164). Runs on exact miss only: * (a) retry `lookupExact` with the `normaliseModelId`-normalized id so * aliases + alias-shadow (#3293) keep working; * (b) identity-match {vendor, family, version} against the load-time * index — version required on both sides (ONE trailing date segment * tolerated on the decorated side, #4183), tier-ordered uniqueness, * fail closed on ambiguity and on sub-SKU size markers (see * model-fuzzy-resolution.ts). * Over-long ids skip the tier entirely (straight to derivation). * `identity` is the caller's already-resolved identity for `modelId` * (#4183 perf: resolved once per getEntry call). */ private lookupFuzzy; /** * Build the entry returned for a fuzzy match: a fresh COPY that keeps the * CALLER'S id and takes behaviour from derivation for that original id — * the matched entry grants pricing/metadata only. */ private resolveMatched; private loadEntries; } /** * Lazy global registry. Most consumers should accept a `ModelRegistry` * via dependency injection instead, but this is the convenient default * for migration from the existing module-level constants. * * The first call constructs the registry and loads the operator * manifest overlay (#2547 4a) from `$NEXUS_MODELS_OVERLAY_PATH` or * `$NEXUS_DATA_DIR/models-manifest.yaml`. Missing / malformed manifests * never throw — rejections are logged at warn level and dropped. */ declare function getDefaultRegistry(): ModelRegistry; /** Replace the global registry. Reserved for tests + bootstrap. */ declare function setDefaultRegistry(registry: ModelRegistry | undefined): void; /** * In-memory, append-only store for task outcomes. * * Provides bounded storage with FIFO eviction, filtering queries, * and aggregated performance summaries. Thread-safe for single-process * use (Node.js event loop). * * @module orchestration/outcomes/outcome-store * (Source: Issue #861 — Task outcome tracking) */ interface OutcomeStoreConfig { readonly maxEntries?: number; /** * Registry used to resolve vendor/family from `outcome.model` at write * time (#2548). Defaults to the process singleton. Pass an explicit * registry for tests that want deterministic resolution without * touching global state. */ readonly registry?: ModelRegistry; } /** * Bounded, append-only, in-memory store for task outcomes. * Evicts oldest entries when capacity is exceeded. */ declare class OutcomeStore { private readonly entries; private readonly maxEntries; private readonly registry; constructor(config?: OutcomeStoreConfig); /** * Append a new outcome. Auto-classifies failures missing failureCategory * (#1441) and resolves the outcome's `vendor` / `family` via the * ModelRegistry (#2548) so family-level retrieval can warm-start * siblings after a model retirement. */ append(outcome: TaskOutcome$1): void; /** * Attach `vendor` and `family` to the outcome if they're not already * set. Idempotent — pre-enriched outcomes pass through unchanged. */ private enrich; /** Query outcomes with optional filters. */ query(filter?: OutcomeQuery): readonly TaskOutcome$1[]; /** * Query outcomes for a specific model with a family-level warm-start * fallback (#2548). When the literal `modelId` has fewer than * `threshold` samples in the store, broaden the result to the model's * `{vendor, family}` siblings — siblings within a family share enough * behavior profile that their outcomes are useful priors for cold * starts after a retirement. * * Returns the outcomes and a `scope` flag so callers know whether * they're consuming literal-id data or family-broadened data. */ queryByModelWithFamilyFallback(modelId: string, options?: { readonly threshold?: number; readonly extraFilter?: Omit; }): { readonly outcomes: readonly TaskOutcome$1[]; readonly scope: 'literal' | 'family' | 'empty'; readonly vendor?: string; readonly family?: string; }; /** Aggregate outcomes into a performance summary. */ summarize(filter?: OutcomeQuery): PerformanceSummary; /** Number of stored outcomes. */ get size(): number; /** Remove all stored outcomes. */ clear(): void; /** * Backfill: reclassify all entries missing failureCategory (#1444). * Also reclassifies 'unknown' entries with no error message as 'execution' * (#1511) since 'unknown' with no diagnostic info is less useful than the * default 'execution' category. * Returns count of reclassified entries. */ reclassifyAll(): number; /** * Purge false failures with zero execution time (#1528). * Removes non-success entries with durationMs=0 — these are either: * - Skipped workers (circuit breaker, role auto-disable) * - Test-generated entries (E2E eval artifacts) * - Pre-execution short-circuits (validation, initialization) * Real model execution always takes >0ms. * Returns count of purged entries. */ purgeSkippedWorkers(): number; private enforceLimit; } /** * Get the shared OutcomeStore singleton. * Returns PersistentOutcomeStore when NEXUS_PERSIST_LEARNING=true * and the factory has been registered (import outcome-store-persistence first). */ declare function getOutcomeStore(): OutcomeStore; /** * Type definitions for the Strategy Distiller. * * Defines the shape of distilled routing rules that are automatically * extracted from observed task outcomes. Rules capture patterns like * "CLI X fails on category Y" and translate them into routing score * adjustments. * * @module learning/strategy-distiller-types * (Source: Issue #999 - Automatic Strategy Distillation) */ /** Status lifecycle for a distilled rule. */ type RuleStatus = 'draft' | 'active' | 'promoted' | 'expired'; /** The type of pattern detected from outcomes. */ type PatternType = 'failure-rate' | 'success-rate' | 'latency-spike'; /** Action to take when a rule matches a routing candidate. */ type StrategyAction = 'penalize' | 'boost' | 'avoid'; /** * A distilled routing rule extracted from outcome patterns. * * Rules are fingerprinted by `patternType:cli:category` to prevent * duplicates and cap total rules at a bounded maximum. */ interface DistilledRule { /** Fingerprint: `${patternType}:${cli}:${category}` */ readonly id: string; /** What kind of pattern triggered this rule */ readonly patternType: PatternType; /** Which CLI this rule applies to */ readonly cli: CliName; /** Task category this rule applies to */ readonly category: string; /** What routing action to take */ readonly action: StrategyAction; /** * Confidence 0-1 = `support × effect` (#5004 finding 3). * * This is the value `DistilledRuleStage.computeDelta` multiplies the base * delta by, so it must answer "how much should routing move" — not "how * many samples did we see". Before #5004 it was the sigmoid over * observations alone, and a rule at 62.5% failure penalised exactly as * hard as one at 100% given the same traffic. */ readonly confidence: number; /** Sample support 0-1: `sigmoidConfidence(observationCount)` (center=30). */ readonly support: number; /** * Effect size 0-1: how far `metric` sits past its detector threshold, * normalised over the remaining headroom — see `effectFor`. Persisted at * distill time because the threshold is config; recomputing it on load * would silently rescale old rules when the threshold changes. */ readonly effect: number; /** Number of observations that informed this rule */ readonly observationCount: number; /** The metric value (failure rate, success rate, or p90/median ratio) */ readonly metric: number; /** Current lifecycle status */ readonly status: RuleStatus; /** Epoch ms when rule was first created */ readonly createdAt: number; /** Epoch ms when rule was last updated */ readonly updatedAt: number; /** * Reserved. **No producer sets this to `true`** (#5853). * * It was documented as a security gate — "tainted rules never promote to * RoutingMemory" — but `upsertRule` writes the literal `false` and is the * only constructor of new rules, so both consumer branches that read it * were unreachable and have been removed. `DistilledRuleStage`, the channel * by which distilled rules actually reach routing, never checked it at all. * * The field stays only because removing a required member of a published * interface is breaking; removal is queued for the next major in #5867. Do * not write a filter against it without first adding a producer — a check * that cannot fail is not a check. */ readonly tainted: boolean; } /** Configuration for the strategy distiller. */ interface DistillerConfig { /** Distill every N outcomes (default: 50) */ readonly triggerThreshold: number; /** Minimum observations before creating a draft rule (default: 3) */ readonly minObservationsForDraft: number; /** Minimum observations before activating a rule (default: 5) */ readonly minObservationsForActive: number; /** * Confidence threshold for promotion to RoutingMemory (default: 0.7). * * @deprecated Only read by `StrategyDistiller.promote()`, which has no * production caller — `DistilledRuleStage` is the single channel by which * distilled rules reach routing (#5004 finding 4). Removal is tracked in * #5467. The gate compares `confidence`, which is now `support × effect`. */ readonly promotionConfidence: number; /** Failure rate above which a failure pattern is detected (default: 0.6) */ readonly failureRateThreshold: number; /** Success rate above which a success pattern is detected (default: 0.8) */ readonly successRateThreshold: number; /** p90/median ratio above which a latency spike is detected (default: 2.0) */ readonly latencyRatioThreshold: number; /** Maximum number of rules to store (default: 90) */ readonly maxRules: number; /** Rule expiry time in ms (default: 24h) */ readonly ruleExpiryMs: number; } /** The detector thresholds `effectFor` normalises a metric against. */ type EffectThresholds = Pick; /** Default distiller configuration. */ declare const DEFAULT_DISTILLER_CONFIG: DistillerConfig; /** Statistics returned by StrategyDistiller.getStats(). */ interface DistillerStats { /** Number of rules in each status */ readonly ruleCountByStatus: Readonly>; /** Total number of rules */ readonly totalRules: number; /** Epoch ms of last distillation run */ readonly lastDistillAt: number | undefined; /** Number of outcomes processed since last distillation */ readonly outcomesSinceLastDistill: number; } /** * Strategy Distiller — Automatic routing rule extraction from outcomes. * * Monitors OutcomeStore data and distills recurring patterns into * routing rules. Three pattern detectors identify failure rates, * success rates, and latency spikes per (cli, category) group. * * Rules progress through a lifecycle: draft -> active -> promoted -> expired. * Tainted rules (from untrusted input) never promote. * * @module learning/strategy-distiller * (Source: Issue #999 - Automatic Strategy Distillation) */ /** * Sample support: 1 / (1 + exp(-(n - center) / 5)). * * This is the `support` factor of a rule's confidence (#5004 finding 3). The * name predates the support/effect split and is kept because it is exported * from the package root. */ declare function sigmoidConfidence(observations: number, center?: number): number; /** * Effect size of a detected pattern in [0, 1] (#5004 finding 3): how far the * metric sits past the detector threshold that produced it, normalised. * * - `failure-rate`: `(rate − failureRateThreshold) / (1 − failureRateThreshold)` * - `success-rate`: `(rate − successRateThreshold) / (1 − successRateThreshold)` * - `latency-spike`: `min(1, (ratio − latencyRatioThreshold) / latencyRatioThreshold)` * * A metric exactly at its threshold is 0: the detector fired, but there is no * margin to act on. A metric at the far end of its scale is 1. Never NaN — a * threshold with no headroom (failure threshold 1.0, latency threshold 0) or a * NaN metric yields 0, so `baseDelta × confidence` in routing stays a number. */ declare function effectFor(patternType: PatternType, metric: number, thresholds: EffectThresholds): number; /** Group outcomes by (cli, category). */ interface OutcomeGroup { readonly cli: CliName; readonly category: string; readonly outcomes: readonly TaskOutcome$1[]; } interface DetectedPattern { readonly cli: CliName; readonly category: string; readonly patternType: PatternType; readonly action: StrategyAction; readonly metric: number; readonly observationCount: number; } /** Detect groups with failure rate above threshold. */ declare function detectFailurePatterns(groups: readonly OutcomeGroup[], threshold: number): DetectedPattern[]; /** Detect groups with success rate above threshold. */ declare function detectSuccessPatterns(groups: readonly OutcomeGroup[], threshold: number): DetectedPattern[]; /** Detect groups with latency spike (p90/median > threshold). */ declare function detectLatencyPatterns(groups: readonly OutcomeGroup[], threshold: number): DetectedPattern[]; /** * Distills outcome patterns into routing rules. * * Subscribe to OutcomeFeedbackCollector.onOutcomeProcessed() and call * onOutcome() for each processed outcome. Distillation triggers * automatically every `triggerThreshold` outcomes. */ declare class StrategyDistiller { /** Protected so `PersistentStrategyDistiller` hydrates legacy rules under the live thresholds. */ protected readonly config: DistillerConfig; private readonly outcomeStore; private readonly logger; private readonly rules; private outcomeCounter; private lastDistillAt; constructor(outcomeStore: OutcomeStore, logger?: ILogger, config?: Partial); /** Called for each processed outcome. Triggers distillation at threshold. */ onOutcome(): void; /** Run distillation on current OutcomeStore data. */ distill(): void; /** Get rules filtered by status. */ getRules(status?: RuleStatus): readonly DistilledRule[]; /** Get distiller statistics. */ getStats(): DistillerStats; /** * Promote high-confidence rules to RoutingMemory. * Rules must be active, with sufficient observations and confidence. * * @deprecated No production caller (#5004 finding 4). `DistilledRuleStage` * is the single channel by which distilled rules reach routing; this * second channel into `RoutingMemory` is kept only so the deprecation is * non-breaking. Removal is tracked in #5467. Note the gate now compares * `confidence = support × effect` against `promotionConfidence`, so a rule * that would have promoted on sample size alone may no longer clear it. */ promote(routingMemory: IRoutingMemory): number; /** Load pre-existing rules (e.g., from disk). Used by PersistentStrategyDistiller. */ protected loadRules(rules: readonly DistilledRule[]): void; private upsertRule; private computeStatus; private expireRules; private enforceMaxRules; /** Convert rule metrics into ModelPerformance for RoutingMemory. */ private ruleToPerformance; } /** Factory function for creating StrategyDistiller. */ declare function createStrategyDistiller(outcomeStore: OutcomeStore, logger?: ILogger, config?: Partial): StrategyDistiller; /** * Distilled Rule Stage * * Applies score adjustments from automatically distilled routing rules. * Rules are produced by StrategyDistiller from observed task outcomes. * * Score-only stage (no filtering): penalize, boost, or avoid adjustments * scaled by rule confidence. Runs at priority 45 (after ZeroRouter 40, * before Preference 50). * * @module cli-adapters/routing/stages/distilled-rule-stage * (Source: Issue #999 - Automatic Strategy Distillation) */ /** Configuration for the distilled rule stage. */ interface DistilledRuleStageConfig { /** Penalty score for penalize action (default: -5) */ readonly penaltyDelta: number; /** Boost score for boost action (default: 5) */ readonly boostDelta: number; /** Avoid score for avoid action (default: -10) */ readonly avoidDelta: number; } /** * Capacity Filter Stage * * Classifies each routing candidate's adapter capacity and reports it. Under * `enforceHardLimits: true` it also excludes measurably exhausted candidates so * a task is not routed to an adapter that cannot serve it (#4373, criterion 3 * of #4351). * * The shipped default is SIGNAL-ONLY — see `DEFAULT_CONFIG` for why, and #4456 * for the missing signal that would make enforcement safe. Criterion 3 of #4351 * is therefore not yet closed. * * This replaces the capacity semantics of the deleted `WorkBalancer` (#4378). * Only the *predicate* was carried over — the queue/dispatch half was the shape * mismatch that decided that vote. Capacity here is a per-candidate decision * input inside the stage chain, not a dashboard. * * @module cli-adapters/routing/stages/capacity-stage * (Source: ADR-0005) */ /** Configuration for the capacity filter stage. */ interface CapacityStageConfig { /** * Whether to enforce exhaustion (filter the candidate out) or merely annotate * it (signal only). Mirrors `BudgetStageConfig.enforceHardLimits` so the two * filters are configured the same way. */ readonly enforceHardLimits: boolean; /** * Per-adapter capacity-probe budget (ms). `ICliAdapter.getCapacity()` is a * promise on a public interface with no timeout of its own, so an adapter that * hangs would hang every routing decision. A probe that overruns is treated as * `unmeasured`, never as exhausted. */ readonly probeTimeoutMs: number; } /** * Interface for routing metrics collection. * Allows dependency injection of RoutingMetricsCollector. * (Source: Issue #559 - Wire RoutingMetricsCollector to CompositeRouter) */ interface IRoutingMetricsCollector { /** Record a routing decision. */ recordDecision(record: RoutingRecord): void; /** Record an outcome for a routing decision. */ recordOutcome(record: OutcomeRecord): void; /** Get metrics for a time period. */ getMetrics(periodHours?: number): RoutingMetrics; } /** * Configuration schema for CompositeRouter. */ declare const CompositeRouterConfigSchema: z.ZodObject<{ enableConfidenceCascade: z.ZodDefault; enableBudgetFilter: z.ZodDefault; enableCapabilityMatch: z.ZodDefault; enableZeroRouter: z.ZodDefault; enablePreferenceRouting: z.ZodDefault; enableTopsisRanking: z.ZodDefault; enableLinUCBSelection: z.ZodDefault; enableQualityConstraint: z.ZodDefault; enableResourceStrategy: z.ZodDefault; enableStrategyDistillation: z.ZodDefault; enableLatencyTracking: z.ZodDefault; enableRoutingMemory: z.ZodDefault; enableKnnRouting: z.ZodDefault; latencyScoreWeight: z.ZodDefault; budgetConstraints: z.ZodOptional; maxCostUsd: z.ZodOptional; maxLatencyMs: z.ZodOptional; taskClassMaxCostUsd: z.ZodOptional & z.core.$partial, z.ZodNumber>>; }, z.core.$strip>>; linucbAlpha: z.ZodDefault; billingMode: z.ZodDefault>; enableCapacityBalancing: z.ZodDefault; maxDecisionTimeMs: z.ZodDefault; preferenceMinDataPoints: z.ZodDefault; }, z.core.$strip>; type CompositeRouterConfig = z.infer; /** * Extended config type that includes preference router and ZeroRouter config. */ interface CompositeRouterConfigWithPreference extends CompositeRouterConfig { /** Confidence cascade stage configuration (optional) (Issue #755) */ confidenceCascadeConfig?: Partial; /** Capability match stage configuration (optional) (Issue #755) */ capabilityMatchConfig?: Partial; /** Quality constraint stage configuration (optional) (Issue #755) */ qualityConstraintConfig?: Partial; /** Resource strategy stage configuration (optional) (Issue #998) */ resourceStrategyConfig?: Partial; /** Distilled rule stage configuration (optional) (Issue #999) */ distilledRuleStageConfig?: Partial; /** * Capacity filter stage configuration (optional) (#4658). * * `enforceHardLimits` was documented as "available for callers who have a * real quota signal" while the sole production construction passed a * hardcoded `{}`, so no caller could set it. The signal exists now — * `CapacityTracker.recordProviderQuotaExhaustion` fires from two adapters on * a durable `RATE_LIMITED` — so the opt-in is real. The default stays * `false`: #4456's signal-only posture is unchanged, it is a choice now * rather than a hardcoding. */ capacityStageConfig?: Partial; /** Preference router configuration (optional, uses defaults if not provided) */ preferenceRouterConfig?: Partial; /** ZeroRouter configuration (optional, uses defaults if not provided) */ zeroRouterConfig?: Partial; /** * TOPSIS ranking configuration (optional, uses defaults if not provided). * * Added in #5785. `adaptRoutingConfig` returned the three sibling stage * configs and dropped this one, and the stage constructed itself with no * arguments — so a `routing.topsis` block in nexus-agents.yaml was * schema-validated, defaulted, and then ignored. */ topsisConfig?: Partial; /** Latency tracker configuration (optional, uses defaults if not provided) (Issue #361) */ latencyTrackerConfig?: Partial; /** Routing memory configuration (optional, uses defaults if not provided) (Issue #463) */ routingMemoryConfig?: Partial; /** Routing metrics collector for observability (optional) (Issue #559) */ metricsCollector?: IRoutingMetricsCollector; /** Orchestration observer for routing decision tracking (optional) (Issue #587) */ orchestrationObserver?: IOrchestrationObserver; /** * (#2540 PR 7) Harness-driven cache of currently-routable models. * When set, the router gates its candidate-CLI list on the cache: * a CLI is excluded if the cache has been queried at least once and * reports zero available models for that source. Unset → no gating * (preserves prior behaviour). */ availableModelsCache?: AvailableModelsCache; } /** * Default configuration. */ declare const DEFAULT_COMPOSITE_CONFIG: CompositeRouterConfig; /** * Routing decision with full explanation. */ interface CompositeRoutingDecision { /** Selected CLI adapter */ readonly adapter: ICliAdapter; /** Selected routing arm — a CLI slot or a distinct `api:*` arm (#3422). */ readonly cliName: RoutingArmId; /** * Concrete model selected by difficulty tier (#3394). Present only when * route-time model selection is enabled (NEXUS_ROUTE_MODEL_SELECTION). * Consumers should use `decision.model ?? getDefaultModelForCli(cliName)`. */ readonly model?: string | undefined; /** Overall confidence in decision (0-1) */ readonly confidence: number; /** Human-readable explanation */ readonly reason: string; /** Stages executed */ readonly stagesExecuted: readonly string[]; /** Decision time in milliseconds */ readonly decisionTimeMs: number; /** Budget feasibility (if budget filter enabled) */ readonly withinBudget?: boolean | undefined; /** ZeroRouter difficulty estimate (if ZeroRouter enabled) */ readonly difficultyEstimate?: DifficultyEstimate | undefined; /** ZeroRouter recommended model tier (if ZeroRouter enabled) */ readonly difficultyTier?: ModelTier$1 | undefined; /** Preference routing score (if preference routing enabled) */ readonly preferenceScore?: number | undefined; /** Selected tier from preference routing */ readonly preferenceTier?: 'strong' | 'weak' | undefined; /** TOPSIS score (if TOPSIS ranking enabled) */ readonly topsisScore?: number | undefined; /** LinUCB UCB score (if LinUCB enabled) */ readonly ucbScore?: number | undefined; /** Latency score (if latency tracking enabled) (Issue #361) */ readonly latencyScore?: number | undefined; /** Alternative adapters in ranked order */ readonly alternatives: readonly RoutingArmId[]; /** * Score per entry in {@link alternatives} (#5269). * * ABSENT when no ranking produced per-arm scores — which is not the same as * every alternative scoring zero. `delegate_to_model` previously had no * per-alternative score available and filled the field with the WINNER's * `topsisScore`, so a caller saw three alternatives scoring alike and read * them as equivalent to each other and to the selection. A reader must treat * absence as "not ranked", never as a measurement. */ readonly alternativeScores?: ReadonlyMap | undefined; /** Task analysis used for routing */ readonly taskProfile: TaskProfile; } /** * Error from composite routing. */ declare class CompositeRoutingError extends Error { readonly stage: string; constructor(message: string, stage: string, cause?: Error); } /** * Router statistics for observability. */ interface CompositeRouterStats { /** Total routing decisions made */ readonly totalDecisions: number; /** Decisions per CLI */ readonly decisionsPerCli: Readonly>; /** Average decision time in ms */ readonly avgDecisionTimeMs: number; /** Budget filter rejection rate */ readonly budgetRejectionRate: number; /** * Capacity filter statistics (#4658), present when the stage is enabled. * * `enforced` is load-bearing: `excludedCount` can only be zero while * enforcement is off, so reporting the count alone presents a default as a * measurement. `enforced: false` says which of the two a zero is. */ readonly capacityStats?: { readonly enforced: boolean; readonly excludedCount: number; }; /** Preference routing statistics */ readonly preferenceStats?: { /** Whether preference routing is enabled */ readonly enabled: boolean; /** Whether sufficient data for preference routing */ readonly hasSufficientData: boolean; /** Total preference data points collected */ readonly dataPointCount: number; /** Strong model preference rate */ readonly strongModelPreferenceRate: number; }; /** LinUCB arm statistics */ readonly banditStats: ReadonlyArray<{ name: string; pullCount: number; avgReward: number; }>; /** Latency tracking statistics (Issue #361) */ readonly latencyStats?: LatencyTrackerStats | undefined; /** Routing memory statistics (Issue #463) */ readonly routingMemoryStats?: RoutingMemoryStats | undefined; } /** Composite router interface for dependency injection. */ interface ICompositeRouter { route(task: CliTask): Promise>; executeTask(task: CliTask): Promise>; /** Record a routing outcome for a distinct routing arm (CLI slot or api:* arm) (#3422). */ recordOutcome(cliName: RoutingArmId, task: CliTask, reward: number, success?: boolean): void; recordPreference(query: string, strongPreferred: boolean, quality?: { strong?: number; weak?: number; }): void; recordDifficultyOutcome(task: CliTask, success: boolean, qualityScore?: number): void; getStats(): CompositeRouterStats; hasMinimumPreferenceData(): boolean; getZeroRouter(): IZeroRouter | undefined; getLatencyTracker(): ILatencyTracker | undefined; getRoutingMemory(): IRoutingMemory | undefined; /** Get the metrics collector (if configured) (Issue #559) */ getMetricsCollector(): IRoutingMetricsCollector | undefined; /** Get the orchestration observer (if configured) (Issue #587) */ getOrchestrationObserver(): IOrchestrationObserver | undefined; } /** CompositeRouter implementation. */ declare class CompositeRouter implements ICompositeRouter { private readonly config; private readonly logger; private readonly adapters; private budgetRouter?; private zeroRouter?; private preferenceRouter?; private topsisRouter?; private linucbBandit?; private latencyTracker?; private routingMemory?; /** * Most recently consulted unified memory context (Phase 3 of #2792). * Set on every {@link route} call so tests + telemetry can inspect what * the router saw at decision time. Typed as `unknown` here to avoid * pulling the typed surface into this module's circular-dep zone — the * field is for observability; callers that need typed reads should call * `getContextForTask` directly. */ private lastUnifiedContext?; /** Metrics collector for routing observability (Issue #559) */ private metricsCollector?; /** Orchestration observer for routing decision tracking (Issue #587) */ private orchestrationObserver?; /** Confidence cascade stage instance (Issue #755) */ private confidenceCascadeStage?; /** Capability match stage instance (Issue #755) */ private capabilityMatchStage?; /** Quality constraint stage instance (Issue #755) */ private qualityConstraintStage?; /** Resource strategy stage instance (Issue #998) */ private resourceStrategyStage?; /** Capacity filter stage instance (#4373, #4351 criterion 3) */ private capacityFilterStage?; /** Distilled rule stage instance (Issue #999) */ private distilledRuleStage?; /** KNN routing stage instance (arXiv:2505.12601) */ private knnRoutingStage?; /** Strategy distiller instance (Issue #999) */ private strategyDistiller?; private readonly cliNames; /** * (#2540 PR 7) Optional harness-driven availability gate. When set, * `executeRouting` filters the candidate CLI list to only those with * ≥1 routable model per the cache. See `getCandidateCliNames`. */ private readonly availableModelsCache?; private totalDecisions; private decisionsPerCli; private totalDecisionTimeMs; private budgetRejections; private lastTraceId?; /** * Route-time outcome data keyed by the exact task object for execution-safe * feedback joins (#4197 shadow glue + difficulty attribution; #6148 split). */ private readonly pendingRoutingOutcomes; constructor(adapters: Map, config?: Partial, logger?: ILogger); /** * Optional collaborators, assigned only when supplied so an absent one stays * `undefined` rather than being stored as a null-ish value. Extracted from * the constructor to keep it under the function-length bar (#4658). */ private assignOptionalCollaborators; private initializeCoreRouters; /** #4196: plumb per-task-class cost ceilings into the BudgetRouter. * Absent → defaults (no ceiling configured). */ private buildBudgetRouter; private initializeMemoryAndStages; private initializeOptionalStages; /** Emit routing.decision event to pipeline event bus (#1687). */ private emitRoutingDecision; /** Warm-start LinUCB bandit from persisted outcomes (Issue #1015). * Uses a 30-day lookback window so stale outcomes don't override * routing changes like primaryCli specialization (#1667). */ private warmStartBandit; private logInitialization; route(task: CliTask): Promise>; /** * Read the unified memory context for this task. Best-effort, never * throws. Sets `this.lastUnifiedContext` so external observers (tests, * telemetry) can inspect what the router consulted at decision time. */ private consultUnifiedContext; /** * Unified method that routes, executes, and auto-records feedback. * Use this for most cases; use route() when you need decision details without execution. * * @param task - Task to execute * @returns Result with CLI response or error */ executeTask(task: CliTask): Promise>; private autoRecordFeedback; /** Task type inference keywords. */ private static readonly TASK_TYPE_KEYWORDS; /** * Infer task type from task content for routing memory. */ private inferTaskType; private executeRouting; /** * (#2540 PR 7) Returns the candidate routing-arm set for the routing pipeline * (`RoutingArmId[]` = CLI slots plus any `api:*` arms, #3422), filtered by * harness-driven availability when the cache is wired. (Name retained for * history; the set is routing arms, not only CLIs.) * * Filtering rules: * - No cache configured → return all registered arms (prior behaviour). * - Cache configured → query getAll(); an arm is excluded only if the * cache reports zero models for it. If the cache returns an empty union * (cold start, all sources failing), fall back to all registered arms * so the router never wedges on a transient cache miss. * - Errors in the cache do not block routing — log and fall through. */ private getCandidateCliNames; /** (#2540 PR 7) Public accessor for the wired cache (or undefined). */ getAvailableModelsCache(): AvailableModelsCache | undefined; /** * The TOPSIS config the ranking stage was actually built with, or undefined * when ranking is disabled (#5785). * * Mirrors `getAvailableModelsCache` above: a narrow accessor so the WIRING is * verifiable, not just the adapter's output. The adapter used to return a * `topsisConfig` that this class never read, and a test asserting only the * adapter would have passed against that. */ getTopsisConfig(): TopsisConfig | undefined; private getStageDependencies; private buildRoutingDecision; private updateStats; /** * Record a routing decision to the orchestration observer (Issue #587). */ private recordToOrchestrationObserver; private handleRoutingError; recordOutcome(cliName: RoutingArmId, task: CliTask, reward: number, success?: boolean): void; recordPreference(query: string, strongModelPreferred: boolean, quality?: { strong?: number; weak?: number; }): void; recordDifficultyOutcome(task: CliTask, success: boolean, qualityScore?: number): void; private recordExecutedDifficultyOutcome; private finishDifficultyOutcome; hasMinimumPreferenceData(): boolean; private getOutcomeDependencies; getZeroRouter(): IZeroRouter | undefined; getLatencyTracker(): ILatencyTracker | undefined; /** * Get the metrics collector (if configured). * (Source: Issue #559 - Wire RoutingMetricsCollector to CompositeRouter) */ getMetricsCollector(): IRoutingMetricsCollector | undefined; /** * Get the orchestration observer (if configured). * (Source: Issue #587 - Wire OrchestrationObserver to CompositeRouter) */ getOrchestrationObserver(): IOrchestrationObserver | undefined; getStats(): CompositeRouterStats; /** Get the routing memory instance (if enabled). */ getRoutingMemory(): IRoutingMemory | undefined; } /** Creates a CompositeRouter instance. */ declare function createCompositeRouter(adapters: Map, config?: Partial, logger?: ILogger): ICompositeRouter; /** * nexus-agents/core - Workflow Types * * Interface for workflow execution engine. */ /** * Budget allocation for context categories. */ interface ContextBudget$1 { /** System instructions and project context (default: 15%) */ system: number; /** Current task description and requirements (default: 20%) */ task: number; /** Active working content (default: 50%) */ active: number; /** Reserved for response generation (default: 15%) */ reserved: number; } /** * Partial context budget for step-level overrides. */ type PartialContextBudget = Partial; /** * Workflow input definition. */ interface InputDefinition { /** Input name */ name: string; /** Input type */ type: 'string' | 'number' | 'boolean' | 'object' | 'array'; /** Description */ description?: string; /** Whether required */ required?: boolean; /** Default value */ default?: unknown; } /** * Single step in a workflow. */ interface WorkflowStep$1 { /** Unique step identifier */ id: string; /** Agent role to execute this step */ agent: AgentRole; /** Action to perform */ action: string; /** Inputs for the step */ inputs: Record; /** Step dependencies (wait for these to complete) */ dependsOn?: string[]; /** Execute in parallel with dependencies */ parallel?: boolean; /** Number of retry attempts */ retries?: number; /** Timeout in ms */ timeout?: number; /** Condition for execution */ condition?: string; /** Step-specific context budget override (merges with workflow default) */ contextBudget?: PartialContextBudget; } /** * Workflow definition (loaded from template). */ interface WorkflowDefinition { /** Workflow name */ name: string; /** Version */ version: string; /** Description */ description?: string; /** Input definitions */ inputs: InputDefinition[]; /** Workflow steps */ steps: WorkflowStep$1[]; /** Global timeout in ms */ timeout?: number; /** Default context budget for workflow steps (individual steps can override) */ defaultBudget?: ContextBudget$1; } /** * Result of step execution. */ interface StepResult { /** Step ID */ stepId: string; /** Step output */ output: unknown; /** Duration in ms */ durationMs: number; /** Status */ status: 'success' | 'failed' | 'skipped'; /** Error message if failed */ error?: string; /** * Real tokens consumed by this step (#4673). * * `undefined` means the step reported no usage — a step that ran no model, * or an adapter that returned none. It does NOT mean zero. That distinction * matters for budgets specifically: silently treating unmeasured as zero * under-counts spend, which is the dangerous direction for a cap. */ tokensUsed?: number; } /** * Result of workflow execution. */ interface WorkflowResult { /** Execution ID */ executionId: string; /** Workflow name */ workflowName: string; /** Step results */ stepResults: StepResult[]; /** Final output */ output: unknown; /** Total duration in ms */ totalDurationMs: number; } /** * Workflow execution status. */ type ExecutionStatus = { state: 'pending'; } | { state: 'running'; currentStep: string; progress: number; } | { state: 'completed'; result: WorkflowResult; } | { state: 'failed'; error: string; failedStep?: string; } | { state: 'cancelled'; cancelledAt: string; }; /** * Workflow template metadata. */ interface WorkflowTemplate { /** Template name */ name: string; /** Version */ version: string; /** Description */ description?: string; /** File path */ path: string; /** Category */ category?: string; } /** * Parse error for workflow templates. */ declare class ParseError extends Error { readonly line: number | undefined; readonly column: number | undefined; constructor(message: string, options?: { line?: number; column?: number; }); } /** * Workflow engine interface. */ interface IWorkflowEngine { /** * Load workflow template from file. * @param path - Path to template file * @returns Result with WorkflowDefinition or ParseError */ loadTemplate(path: string): Promise>; /** * Execute a workflow with inputs. * @param workflow - Workflow definition * @param inputs - Input values * @param options - Optional execution overrides. `phaseTimeoutMs` (#3017) * overrides the per-phase execution timeout for this run only — wins * over both `workflow.timeout` (set in the template YAML) and the * engine's `defaultTimeoutMs`. `onPhaseComplete` (#6162) is called after * each phase settles — the async-job liveness heartbeat for `run_workflow`. * @returns Result with WorkflowResult or WorkflowError */ execute(workflow: WorkflowDefinition, inputs: Record, options?: { phaseTimeoutMs?: number; onPhaseComplete?: () => void; }): Promise>; /** * Get execution status. * @param executionId - Execution ID to check * @returns Current execution status */ getStatus(executionId: string): ExecutionStatus; /** * Cancel a running workflow. * @param executionId - Execution ID to cancel * @returns Result with void or WorkflowError */ cancel(executionId: string): Promise>; /** * List available workflow templates. * @returns Array of available templates */ listTemplates(): Promise; /** * Get a built-in or registered template definition by name. * @param name - Template name (e.g., 'code-review') * @returns The workflow definition, or undefined if not found */ getTemplateByName(name: string): Promise; } /** * nexus-agents/core - Orchestrator Types * * Unified interface for orchestration strategies. * Per System Mandate Loop I - Single canonical path for orchestration. * * Implementations: * - TechLead: LLM-based task decomposition and expert selection * - PuppeteerOrchestrator: Policy-based step execution with learning * - WorkflowEngine: Static template-based workflow execution * * @see docs/adr/0002-orchestrator-interface.md for decision rationale */ /** * Orchestration strategy type. */ type OrchestratorType = 'orchestrator' | 'puppeteer' | 'workflow' | 'custom'; /** * Orchestrator execution options. */ interface OrchestratorExecuteOptions { /** Abort signal for cancellation */ signal?: AbortSignal; /** Maximum execution time in ms */ timeout?: number; /** Maximum number of steps/iterations */ maxSteps?: number; /** Token budget for LLM calls */ tokenBudget?: number; /** Callback for progress updates */ onProgress?: (status: ExecutionStatus) => void; /** Additional metadata passed to orchestrator */ metadata?: Record; } /** * Orchestrator definition - the input that defines what to orchestrate. * This is a discriminated union to support different orchestration styles. */ type OrchestratorDefinition = { type: 'task'; task: Task$1; } | { type: 'workflow'; templatePath: string; } | { type: 'policy'; policyId: string; initialState: Record; }; /** * Step in an orchestration execution. */ interface OrchestratorStep { /** Step identifier */ id: string; /** Agent that executed the step */ agentId: string; /** Agent role */ role: AgentRole; /** Step action/description */ action: string; /** Step output */ output: unknown; /** Duration in ms */ durationMs: number; /** Tokens used in this step. Meaningful only when {@link OrchestratorStep.tokensMeasured} is not `false`. */ tokensUsed: number; /** * Whether `tokensUsed` is a measurement (#4829). * * `false` means no usage was reported for this step, so `tokensUsed` is a * placeholder `0` and NOT a count. Absent means the producer predates the * distinction — unknown, not measured. Mirrors `ResultMetadata.tokensMeasured` * (#4734). */ tokensMeasured?: boolean; /** Status */ status: 'success' | 'failed' | 'skipped'; /** Error if failed */ error: string | undefined; } /** * Result of orchestration execution. */ interface OrchestratorResult { /** Unique execution ID */ executionId: string; /** Orchestrator type that executed */ orchestratorType: OrchestratorType; /** Steps executed */ steps: OrchestratorStep[]; /** Final aggregated output */ output: unknown; /** Total execution time in ms */ totalDurationMs: number; /** Total tokens consumed. Meaningful only when {@link OrchestratorResult.tokensMeasured} is not `false`. */ totalTokensUsed: number; /** * Whether `totalTokensUsed` is a measurement (#4829). * * `false` means no step reported usage, so the total is a placeholder `0` * and NOT a count — for anything cap-shaped, reading it as a count * under-counts in the dangerous direction. */ tokensMeasured?: boolean; /** Agents involved */ agentsUsed: string[]; /** * CLI used by the last model-backed step, when known. * * A run may use several CLIs after failover across steps. This field names * only the last executed step's CLI; it is not an aggregate. */ readonly executedCli?: CliNameLiteral; /** Whether the executed CLI identity was measured or remains unknown. */ readonly executedCliSource?: 'executed' | 'unknown'; } /** * Orchestrator error with context. */ declare class OrchestratorError extends Error { readonly name: "OrchestratorError"; readonly code: OrchestratorErrorCode; readonly step: string | undefined; readonly cause: Error | undefined; constructor(message: string, code: OrchestratorErrorCode, options?: { step?: string; cause?: Error; }); } /** * Error codes for orchestrator failures. */ type OrchestratorErrorCode = 'TIMEOUT' | 'CANCELLED' | 'STEP_FAILED' | 'AGENT_ERROR' | 'BUDGET_EXCEEDED' | 'INVALID_DEFINITION' | 'NO_AGENTS_AVAILABLE' | 'POLICY_VIOLATION'; /** * Unified orchestrator interface. * * This interface provides a canonical path for all orchestration * in the system, regardless of the underlying strategy. * * @example * ```typescript * const orchestrator: IOrchestrator = factory.create('orchestrator'); * * const result = await orchestrator.execute( * { type: 'task', task: myTask }, * { timeout: 30000 } * ); * * if (result.ok) { * console.log('Output:', result.value.output); * } * ``` */ interface IOrchestrator { /** Unique orchestrator instance ID */ readonly id: string; /** Orchestrator type */ readonly type: OrchestratorType; /** * Execute an orchestration. * * @param definition - What to orchestrate (task, workflow, or policy) * @param inputs - Input values for the orchestration * @param options - Execution options (timeout, budget, callbacks) * @returns Result with OrchestratorResult or OrchestratorError */ execute(definition: OrchestratorDefinition, inputs: Record, options?: OrchestratorExecuteOptions): Promise>; /** * Get status of an execution. * * @param executionId - Execution ID to check * @returns Current execution status */ getStatus(executionId: string): ExecutionStatus; /** * Cancel a running execution. * * @param executionId - Execution ID to cancel * @param reason - Optional cancellation reason * @returns Result with void or OrchestratorError */ cancel(executionId: string, reason?: string): Promise>; /** * Register an agent with this orchestrator. * Optional - not all orchestrators manage agent pools. * * @param agent - Agent to register */ registerAgent?(agent: IAgent): void; /** * Unregister an agent. * Optional - not all orchestrators manage agent pools. * * @param agentId - Agent ID to unregister */ unregisterAgent?(agentId: string): void; /** * List registered agents. * Optional - not all orchestrators manage agent pools. * * @returns Array of registered agent IDs and roles */ listAgents?(): Array<{ id: string; role: AgentRole; }>; /** * Get execution history. * Optional - for orchestrators that track history. * * @param limit - Maximum number of executions to return * @returns Array of past execution results */ getHistory?(limit?: number): OrchestratorResult[]; } /** * Factory for creating orchestrators. */ interface IOrchestratorFactory { /** * Create an orchestrator instance. * * @param type - Orchestrator type * @param config - Optional configuration * @returns New orchestrator instance */ create(type: OrchestratorType, config?: Record): IOrchestrator; /** * List available orchestrator types. */ listTypes(): OrchestratorType[]; } /** * nexus-agents/core - Registry Interface * * Unified interface for registry implementations. * Provides consistent API across ExpertRegistry, TemplateRegistry, etc. * * (Source: Issue #596 - Unify registry APIs) */ /** * Base interface for registry items. * All registrable items must have an ID. */ interface IRegistryItem { /** Unique identifier for the item */ readonly id: string; } /** * Options for registering an item. */ interface IRegisterOptions { /** Whether to replace if item with same ID exists */ replace?: boolean; } /** * Statistics about a registry. */ interface IRegistryStats { /** Total number of registered items */ total: number; /** Additional stats specific to the registry type */ [key: string]: unknown; } /** * Unified registry interface. * * Provides consistent CRUD and query operations for all registries. * Domain-specific methods can be added as extensions. * * @template T - Type of items stored in the registry * @template E - Error type for failed operations */ interface IRegistry { /** * Register an item in the registry. * * @param item - Item to register * @param options - Registration options * @returns Result indicating success or error */ register(item: T, options?: IRegisterOptions): Result; /** * Unregister an item by ID. * * @param id - Item ID to unregister * @returns Result with the removed item or error */ unregister(id: string): Result; /** * Get an item by ID. * * @param id - Item ID to retrieve * @returns Result with item or error */ get(id: string): Result; /** * Check if an item is registered. * * @param id - Item ID to check * @returns True if item is registered */ has(id: string): boolean; /** * Get all registered items. * * @returns Array of all registered items */ getAll(): T[]; /** * Get all registered item IDs. * * @returns Array of all registered IDs */ getAllIds(): string[]; /** * Search items by predicate. * * @param predicate - Function to test each item * @returns Array of matching items */ query(predicate: (item: T) => boolean): T[]; /** * Search items by text query. * * @param searchTerm - Search term to match against item fields * @returns Array of matching items */ search(searchTerm: string): T[]; /** * Get the number of registered items. */ readonly size: number; /** * Check if the registry is empty. */ readonly isEmpty: boolean; /** * Clear all registered items. */ clear(): void; /** * Get statistics about the registry. */ getStats(): IRegistryStats; } /** * Type definitions for configuration defaults. * * Provides type safety for the centralized defaults system. * * @module config/defaults-types */ /** * Task complexity levels for CLI timeout selection. */ type TaskComplexity = 'simple' | 'standard' | 'complex'; /** * Timeout profile structure for CLI tools. */ interface TimeoutProfile { /** Timeout for simple tasks (single function, quick analysis) in ms */ readonly simple: number; /** Timeout for standard tasks (multi-file changes, moderate analysis) in ms */ readonly standard: number; /** Timeout for complex tasks (codebase-wide changes, deep analysis) in ms */ readonly complex: number; } /** * Env resolver for the single-model `custom-openai` gateway path (#4392 * increment 3). * * Two mechanisms read an OpenAI-compatible gateway from the environment: * * A. the single-model SDK path — `SdkAdapter({ providerId: 'custom-openai' })` * via `auto-adapter.ts`, which mints the `api:custom-openai` routing arm * under `NEXUS_BILLING_MODE=api`; * B. the discovery path — `openai-compat-adapter.ts`, which lists the * gateway's models, serves voters in-process and registers ONE * `api:` arm. * * Both take a base URL and a key. Mechanism A historically read * `NEXUS_CUSTOM_API_BASE_URL` / `NEXUS_CUSTOM_API_KEY`; mechanism B reads * `NEXUS_OPENAI_COMPAT_URL` / `NEXUS_OPENAI_COMPAT_KEY`. This module makes the * old pair a deprecated ALIAS of the new pair for mechanism A only — a pure * rename shim, resolution `new ?? old` per variable (panel * vote-1789558437481-yup142p runoff, option C). Mechanism B is deliberately * NOT fed from the alias: renaming to the new names is what opts an operator * into the gateway path, and the deprecation warn says so. The aliases are * dropped in the next major (#6291). * * @module adapters/sdk/gateway-env */ /** One deprecated gateway env name found set in the environment. */ interface DeprecatedGatewayEnvUse { readonly name: string; readonly replacement: string; /** True when the replacement is also set, so this alias is ignored. */ readonly shadowed: boolean; } /** * Centralized Zod schema for NEXUS_* environment variables (Issue #1016) * * Validates all known NEXUS_* env vars at startup (warn-only, never blocks). * Detects typos via Levenshtein distance and suggests corrections. * * Does NOT replace per-module parsing (parseIntEnv, resolveV2Config, etc.). * This is an additional safety net run once at startup. * * @module config/env-schema */ /** An unknown NEXUS_* env var with optional typo suggestion. */ interface UnknownVar { readonly name: string; readonly suggestion: string | null; } /** An invalid NEXUS_* env var with error message. */ interface InvalidVar { readonly name: string; readonly value: string; readonly error: string; } /** * A variable that is spelled correctly, holds a valid value, and still changes * nothing — the request was reduced by a downstream clamp. * * This is the category the report was missing. "Unknown" catches a typo and * "invalid" catches a bad value; a correctly-set variable that is silently * capped passes both and does nothing, which is the failure mode #5155 named * for the boolean flags and which the timeout knobs still had. */ interface IneffectiveVar { readonly name: string; readonly requestedMs: number; readonly effectiveMs: number; readonly reason: string; } /** * A deprecated alias that is set: which name replaces it, and whether the * replacement is also set (in which case the alias is ignored). Currently * the two gateway aliases of #4392 increment 3. */ type DeprecatedVar = DeprecatedGatewayEnvUse; /** Result of validating NEXUS_* environment variables. */ interface EnvValidationResult { readonly unknownVars: readonly UnknownVar[]; readonly invalidVars: readonly InvalidVar[]; readonly ineffectiveVars: readonly IneffectiveVar[]; /** * Deprecated names in use (#4392 increment 3). Optional so a caller that * builds this shape by hand keeps compiling; `validateNexusEnv` always * fills it, empty when none is set. */ readonly deprecatedVars?: readonly DeprecatedVar[]; } /** * Validates all NEXUS_* environment variables. * * - Detects unknown vars (potential typos) with Levenshtein suggestions * - Detects invalid values for known vars * - Reports deprecated aliases in use (not logged here — see * {@link logValidationWarnings}) * - Warn-only: never throws, never blocks startup * * @param logger - Optional logger for direct warning output * @returns Validation result with unknown and invalid var lists */ declare function validateNexusEnv(logger?: ILogger): EnvValidationResult; /** * Returns all known NEXUS_* variable names from the schema. */ declare function getKnownNexusVarNames(): readonly string[]; /** * nexus-agents/config - Model Availability Probes & Fallback Chains * * Runtime availability tracking for model APIs. Maintains a bounded * TTL cache of probe results and provides fallback chain resolution * when a model is unavailable. * * @module config/model-availability * (Source: Issue #869) */ /** Status of a model probe. */ interface ProbeResult { readonly modelId: ModelId; readonly available: boolean; readonly latencyMs: number; readonly checkedAt: number; readonly error?: string; } /** Configuration for the availability cache. */ interface AvailabilityCacheConfig { /** Time-to-live in ms for probe results. Default: 60_000 (1 min). */ readonly ttlMs?: number; /** Maximum entries in the cache. Default: 50. */ readonly maxEntries?: number; } /** A function that probes whether a model is reachable. */ type ProbeFn = (modelId: ModelId) => Promise; /** Fallback chain entry with model and reason for fallback. */ interface FallbackEntry { readonly modelId: ModelId; readonly reason: string; } /** * Bounded TTL cache for model availability probe results. * Thread-safe for single-threaded Node.js; no locks needed. */ declare class AvailabilityCache { private readonly cache; private readonly ttlMs; private readonly maxEntries; constructor(config?: AvailabilityCacheConfig); /** Get a cached probe result, or undefined if expired/missing. */ get(modelId: ModelId): ProbeResult | undefined; /** Store a probe result, evicting oldest if at capacity. */ set(result: ProbeResult): void; /** Mark a model as unavailable without a full probe. */ markUnavailable(modelId: ModelId, error: string): void; /** Mark a model as available. */ markAvailable(modelId: ModelId, latencyMs: number): void; /** Check if a model is known-unavailable (cached and not expired). */ isKnownUnavailable(modelId: ModelId): boolean; /** Get all cached entries (for diagnostics). */ entries(): ReadonlyArray; /** Number of cached entries. */ get size(): number; /** Clear all cached entries. */ clear(): void; } /** * Resolves a fallback chain for a given model. * Returns the first available model in the chain, skipping known-unavailable ones. */ declare function resolveFallback(modelId: ModelId, cache: AvailabilityCache): FallbackEntry | null; /** * Get the fallback chain for a CLI tool. */ declare function getFallbackChain(cli: CliNameLiteral): readonly ModelId[]; /** * Get the CLI name for a model ID. */ declare function getCliForModelId(modelId: ModelId): CliNameLiteral | undefined; /** Get the shared availability cache (lazy-init). */ declare function getAvailabilityCache(): AvailabilityCache; /** Reset the global cache (for testing). */ declare function resetAvailabilityCache(): void; /** * Filters out known-unavailable models from a set of model IDs. * Returns the filtered set, or null if no models were removed. * Used by scoreAllModels() to skip unavailable models. */ declare function filterAvailableModels(modelIds: readonly string[], cache: AvailabilityCache): { available: string[]; removed: string[]; }; /** * nexus-agents/adapters - Adapter Factory * * Registry-based factory for creating model adapters. * Provides a centralized way to register and create adapters for different providers. */ /** * Zod schema for adapter configuration. * Validates configuration before creating adapters. */ declare const AdapterConfigSchema: z.ZodObject<{ providerId: z.ZodString; modelId: z.ZodString; apiKey: z.ZodOptional; baseUrl: z.ZodOptional; timeout: z.ZodOptional; maxRetries: z.ZodOptional; }, z.core.$strip>; /** * Adapter configuration type inferred from schema. */ type AdapterConfig = z.infer; /** * Factory function type for creating adapters. * Each provider registers a creator function that produces adapters. * * @param config - The validated adapter configuration * @returns A configured model adapter instance */ type AdapterCreator = (config: AdapterConfig) => IModelAdapter; /** * Options for registering an adapter provider. */ interface RegisterOptions$1 { /** Whether to allow overwriting an existing provider */ allowOverwrite?: boolean; } /** * Factory for creating and managing model adapters. * * Implements the registry pattern to allow dynamic registration of adapter * creators for different model providers. This enables a plugin-style * architecture where new providers can be added without modifying core code. * * @example * ```typescript * const factory = new AdapterFactory(); * * // Register a provider * factory.register('anthropic', (config) => new ClaudeAdapter(config)); * * // Create an adapter * const result = factory.create({ * providerId: 'anthropic', * modelId: 'claude-sonnet-4' * }); * * if (result.ok) { * const adapter = result.value; * // Use adapter... * } * ``` */ declare class AdapterFactory { /** * Registry mapping provider IDs to their creator functions. */ private readonly registry; /** * Registers an adapter creator for a provider. * * @param providerId - Unique identifier for the provider (e.g., 'anthropic') * @param creator - Factory function that creates adapters for this provider * @param options - Registration options * @returns Result indicating success or failure * * @example * ```typescript * const result = factory.register('anthropic', (config) => new ClaudeAdapter(config)); * if (!result.ok) { * console.error('Registration failed:', result.error.message); * } * ``` */ register(providerId: string, creator: AdapterCreator, options?: RegisterOptions$1): Result; /** * Unregisters an adapter creator for a provider. * * @param providerId - The provider ID to unregister * @returns Result indicating whether the provider was removed */ unregister(providerId: string): Result; /** * Creates an adapter instance for the specified configuration. * * Validates the configuration against the schema, looks up the provider * in the registry, and invokes the creator function to produce an adapter. * * @param config - Adapter configuration specifying provider and settings * @returns Result containing the adapter or a ConfigError * * @example * ```typescript * const result = factory.create({ * providerId: 'anthropic', * modelId: 'claude-sonnet-4', * timeout: 30000, * maxRetries: 3 * }); * * if (result.ok) { * const response = await result.value.complete(request); * } else { * console.error('Failed to create adapter:', result.error.message); * } * ``` */ create(config: AdapterConfig): Result; /** * Validates adapter configuration against the schema. */ private validateConfig; /** * Invokes the creator function to create an adapter. */ private invokeCreator; /** * Handles errors thrown by adapter creator functions. */ private handleCreatorError; /** * Checks if a provider is registered. * * @param providerId - The provider ID to check * @returns True if the provider is registered */ hasProvider(providerId: string): boolean; /** * Returns a list of all registered provider IDs. * * @returns Array of provider identifiers */ listProviders(): string[]; /** * Returns the number of registered providers. * * @returns Count of registered providers */ get size(): number; /** * Clears all registered providers. * Useful for testing or resetting the factory state. */ clear(): void; /** * Sanitizes configuration for logging by removing sensitive fields. * * @param config - Configuration to sanitize * @returns Sanitized configuration safe for logging */ private sanitizeConfig; } /** * nexus-agents/adapters - Token Bucket Rate Limiter * * A rate limiter implementation using the token bucket algorithm. * Tokens are added to the bucket at a fixed rate up to a maximum capacity. * Each operation consumes tokens; operations are rejected when insufficient tokens. * * @see https://en.wikipedia.org/wiki/Token_bucket */ /** * Configuration options for the RateLimiter. */ interface RateLimiterConfig { /** * Maximum number of tokens the bucket can hold. * This is also the initial token count. */ readonly capacity: number; /** * Number of tokens added to the bucket per second. */ readonly refillRate: number; /** * Interval in milliseconds for automatic refill checks. * Only used when waiting for tokens. Default: 100ms. */ readonly refillInterval?: number; } /** * Error returned when rate limit is exceeded. */ interface RateLimitExceeded { readonly type: 'rate_limit_exceeded'; readonly requested: number; readonly available: number; readonly retryAfterMs: number; } /** * Token bucket rate limiter for controlling request rates. * * The token bucket algorithm works as follows: * 1. A bucket holds tokens up to a maximum capacity * 2. Tokens are added at a fixed rate (refillRate per second) * 3. Each request consumes one or more tokens * 4. If insufficient tokens, the request is rejected or waits * * @example * ```typescript * const limiter = new RateLimiter({ * capacity: 100, // Max 100 tokens * refillRate: 10, // 10 tokens per second * }); * * if (limiter.tryAcquire()) { * // Proceed with operation * } else { * // Rate limited * } * * // Or wait for tokens * await limiter.waitForTokens(); * ``` */ declare class RateLimiter { private readonly capacity; private readonly refillRate; private readonly refillInterval; private tokens; private lastRefillTime; /** * Creates a new RateLimiter instance. * * @param config - Configuration options * @throws {RateLimitError} If configuration is invalid */ constructor(config: RateLimiterConfig); /** * Validates the configuration parameters. */ private validateConfig; /** * Refills tokens based on elapsed time since last refill. * Called automatically before token operations. */ private refill; /** * Attempts to acquire the specified number of tokens. * * @param tokens - Number of tokens to acquire (default: 1) * @returns true if tokens were acquired, false if rate limited * * @example * ```typescript * if (limiter.tryAcquire(5)) { * // Acquired 5 tokens * } * ``` */ tryAcquire(tokens?: number): boolean; /** * Attempts to acquire tokens and returns a Result with detailed information. * * @param tokens - Number of tokens to acquire (default: 1) * @returns Result containing void on success, or RateLimitExceeded on failure * * @example * ```typescript * const result = limiter.acquire(5); * if (!result.ok) { * console.log(`Retry after ${result.error.retryAfterMs}ms`); * } * ``` */ acquire(tokens?: number): Result; /** * Waits until the specified number of tokens are available, then acquires them. * * @param tokens - Number of tokens to acquire (default: 1) * @returns Promise that resolves when tokens are acquired * @throws {RateLimitError} If tokens exceed capacity (would wait forever) * * @example * ```typescript * await limiter.waitForTokens(10); * // 10 tokens acquired * ``` */ waitForTokens(tokens?: number): Promise; /** * Sleeps for the specified duration. */ private sleep; /** * Returns the current number of available tokens. * Performs a refill before returning the count. * * @returns Number of available tokens (may be fractional) */ getRemainingTokens(): number; /** * Returns the number of whole tokens available. * * @returns Integer number of available tokens */ getAvailableTokens(): number; /** * Resets the rate limiter to its initial state. * The bucket is refilled to capacity. */ reset(): void; /** * Returns the bucket's maximum capacity. */ getCapacity(): number; /** * Returns the refill rate in tokens per second. */ getRefillRate(): number; /** * Calculates the time in milliseconds until the specified tokens are available. * * @param tokens - Number of tokens needed (default: 1) * @returns Time in milliseconds until tokens are available, 0 if already available */ getTimeUntilAvailable(tokens?: number): number; } /** * Creates a rate limiter with the specified configuration. * Factory function for cleaner API. * * @param config - Rate limiter configuration * @returns A new RateLimiter instance * * @example * ```typescript * const limiter = createRateLimiter({ * capacity: 100, * refillRate: 10, * }); * ``` */ declare function createRateLimiter(config: RateLimiterConfig): RateLimiter; /** * Async Utilities * * Centralized async helper functions for delay, timeout, and promise utilities. * Consolidates 9+ duplicate sleep/delay implementations across the codebase. * * @module utils/async-utils * (Source: LOOP H-K consolidation) */ /** * Creates a promise that resolves after the specified delay. * Alias: `delay` (both names are exported for compatibility) * * @param ms - Delay in milliseconds * @returns Promise that resolves after the delay * * @example * ```typescript * await sleep(1000); // Wait 1 second * await delay(500); // Wait 500ms (alias) * ``` */ declare function sleep(ms: number): Promise; /** * nexus-agents/adapters - Retry Logic with Exponential Backoff * * Provides generic, type-parameterized retry functionality for fallible * operations with exponential backoff and jitter to prevent thundering * herd problems. Returns Result — type-safe error * boundary suitable for cross-layer use. * * Sibling implementation (see #2230): cli-retry-loop.ts holds a CLI-specific * retry loop with built-in circuit-breaker integration, FailureCategory * mapping, and CliResponse return shape. Don't reach for that one from * non-CLI code; don't reach for this one when you need circuit-breaker * coupling. Math primitives differ deliberately: * - this file: 0-indexed attempt, ±jitterFactor, cap-before-jitter * - cli-retry-loop.ts: 1-indexed attempt, +0..30% jitter, cap-after * * If you find yourself writing a third retry loop: stop, run * `consensus_vote` with scope_steward in the panel, and pick whichever * of these two fits — don't add a third. * * (Source: AWS Architecture Blog - Exponential Backoff and Jitter) * (Source: Google Cloud API Design Guide - Retry Strategy) */ /** * Configuration for retry behavior. */ interface RetryConfig { /** Maximum number of retry attempts. Default: 3 */ readonly maxRetries: number; /** Base delay in milliseconds between retries. Default: 1000 */ readonly baseDelayMs: number; /** Maximum delay in milliseconds between retries. Default: 30000 */ readonly maxDelayMs: number; /** Jitter factor (0-1) to randomize delay. Default: 0.1 (10%) */ readonly jitterFactor: number; } /** * Default retry configuration. * Derived from canonical source: config/defaults.ts RETRY_DEFAULTS */ declare const DEFAULT_RETRY_CONFIG: Readonly; /** * Information about a retry attempt for logging/debugging. */ interface RetryAttemptInfo { /** Current attempt number (1-based) */ readonly attempt: number; /** Maximum attempts allowed */ readonly maxAttempts: number; /** Delay before next retry in milliseconds */ readonly delayMs: number; /** The error that triggered the retry */ readonly error: unknown; } /** * Error thrown when all retry attempts are exhausted. */ declare class RetryExhaustedError extends NexusError { /** Number of attempts made */ readonly attempts: number; /** The last error encountered */ readonly lastError: unknown; constructor(attempts: number, lastError: unknown); } /** * Calculates delay with exponential backoff and jitter. * * Uses full jitter strategy: delay = random(0, min(maxDelay, baseDelay * 2^attempt)) * * @param attempt - Current attempt number (0-based) * @param config - Retry configuration * @returns Delay in milliseconds */ declare function calculateDelay(attempt: number, config: RetryConfig): number; /** * Determines if an error is retryable based on its type, status code, or message. * * Retryable errors include: * - HTTP 429 (Too Many Requests) * - HTTP 5xx (Server Errors) * - HTTP 408 (Request Timeout) * - Network errors (connection reset, timeout, etc.) * - NexusError with rate limit or timeout codes * * Non-retryable errors include: * - HTTP 400, 401, 403, 404 (Client Errors) * - Validation errors * - Authentication errors * * @param error - The error to check * @returns True if the error is retryable */ declare function isRetryableError$1(error: unknown): boolean; /** * Options for withRetry function. */ interface WithRetryOptions { /** Retry configuration. Defaults to DEFAULT_RETRY_CONFIG. */ readonly config?: Partial; /** Custom predicate to determine if an error is retryable. Defaults to isRetryableError. */ readonly isRetryable?: (error: unknown) => boolean; /** Callback invoked before each retry attempt. Useful for logging. */ readonly onRetry?: (info: RetryAttemptInfo) => void; /** * Aborts the retry loop, including the backoff wait (#4293 item 5). * * Without this the backoff was a bare `await sleep(delayMs)`: a cancelled * operation still held real wall-clock time before the loop noticed, and with * the default profile a caller could wait out the full delay for work nobody * wanted any more. * * On abort the loop returns `err(RetryExhaustedError)` rather than throwing — * `withRetry`'s never-throws contract is what `execute_expert` relies on, so * the abort path must be an error VALUE. `RetryExhaustedError.cause` carries * whichever error the last attempt produced, or the signal's abort reason when * the abort arrived before any attempt failed. */ readonly signal?: AbortSignal; } /** * Executes an operation with retry logic using exponential backoff. * * @template T - The return type of the operation * @param operation - The async operation to execute * @param options - Retry options (config, isRetryable predicate, onRetry callback) * @returns A Result containing either the operation result or a RetryExhaustedError * * @example * ```typescript * const result = await withRetry( * () => fetchData('/api/data'), * { config: { maxRetries: 5 } } * ); * * if (result.ok) { * console.log(result.value); * } else { * console.error('All retries failed:', result.error); * } * ``` */ declare function withRetry(operation: () => Promise, options?: WithRetryOptions): Promise>; /** * Wraps an async function with retry logic. * * @template TArgs - The argument types of the function * @template TReturn - The return type of the function * @param fn - The function to wrap * @param options - Retry options * @returns A wrapped function that will retry on failure * * @example * ```typescript * const fetchWithRetry = withRetryWrapper( * async (url: string) => fetch(url), * { config: { maxRetries: 3 } } * ); * * const result = await fetchWithRetry('https://api.example.com/data'); * ``` */ declare function withRetryWrapper(fn: (...args: TArgs) => Promise, options?: WithRetryOptions): (...args: TArgs) => Promise>; /** * nexus-agents/adapters - Base Adapter * * Abstract base class that all model adapters extend. * Provides common functionality for token counting, logging, error transformation, * and capability checking. */ /** * Configuration options for BaseAdapter. */ interface BaseAdapterConfig { /** Provider identifier (e.g., 'anthropic', 'openai') */ providerId: string; /** Model identifier (e.g., 'claude-sonnet-4', 'gpt-4o') */ modelId: string; /** Capabilities this model supports */ capabilities: readonly ModelCapability[]; /** Optional custom logger */ logger?: ILogger; /** API key for authentication (optional, may come from environment) */ apiKey?: string; /** Base URL for the API (optional, uses provider default) */ baseUrl?: string; /** Request timeout in milliseconds */ timeout?: number; /** Maximum number of retries for failed requests */ maxRetries?: number; } /** * Extended ModelError that supports specific error codes. * * While ModelError from core uses MODEL_ERROR by default, this subclass * allows adapters to specify more granular error codes like * MODEL_RATE_LIMITED, MODEL_TIMEOUT, etc. * * Extends ModelError so `instanceof ModelError` checks pass naturally * without requiring `as unknown as ModelError` casts. */ declare class AdapterModelError extends ModelError { constructor(message: string, options: NexusErrorOptions); } /** * Abstract base class for model adapters. * * Provides default implementations for common adapter functionality while * leaving the core API interaction methods abstract for provider-specific * implementations. * * @example * ```typescript * class ClaudeAdapter extends BaseAdapter { * constructor(config: ClaudeAdapterConfig) { * super({ * providerId: 'anthropic', * modelId: config.modelId, * capabilities: [ModelCapability.COMPLETION, ModelCapability.STREAMING], * apiKey: config.apiKey, * }); * } * * async complete(request: CompletionRequest): Promise> { * this.logRequest(request); * // Provider-specific implementation... * } * * async *stream(request: CompletionRequest): AsyncIterable { * this.logRequest(request); * // Provider-specific streaming implementation... * } * } * ``` */ declare abstract class BaseAdapter implements IModelAdapter { readonly providerId: string; readonly modelId: string; readonly capabilities: readonly ModelCapability[]; /** Logger for request/response logging */ protected readonly logger: ILogger; /** Configuration for the adapter */ protected readonly config: BaseAdapterConfig; /** * Creates a new BaseAdapter instance. * * @param config - Adapter configuration */ constructor(config: BaseAdapterConfig); /** * Send a completion request to the model. * Must be implemented by concrete adapter classes. * * @param request - The completion request * @returns Result with response or ModelError */ abstract complete(request: CompletionRequest): Promise>; /** * Stream a completion request from the model. * Must be implemented by concrete adapter classes. * * @param request - The completion request * @yields StreamChunk objects as they arrive */ abstract stream(request: CompletionRequest): AsyncIterable; /** * Count tokens in text using the unified TokenEstimator. * * This provides a reasonable estimate for most use cases. * Concrete adapters may override this with provider-specific tokenizers. * * @param text - Text to count tokens for * @returns Approximate token count */ countTokens(text: string): Promise; /** * Validate adapter configuration. * * Checks that required configuration fields are present and valid. * Concrete adapters may override to add provider-specific validation. * * @returns Ok if valid, ConfigError if invalid */ validateConfig(): Result; /** * Check if this adapter supports a specific capability. * * @param capability - The capability to check for * @returns True if the capability is supported */ hasCapability(capability: ModelCapability): boolean; /** * Log details about an outgoing request. * Sanitizes sensitive information before logging. * * @param request - The completion request to log */ protected logRequest(request: CompletionRequest): void; /** * Log details about a received response. * * @param response - The completion response to log */ protected logResponse(response: CompletionResponse): void; /** * Transform a provider-specific error into a standardized ModelError. * * Maps common error patterns to appropriate error codes: * - Rate limiting (429, quota exceeded) * - Timeouts (ETIMEDOUT, ESOCKETTIMEDOUT) * - Authentication (401, 403) * - Model unavailable (503, 502) * * @param error - The original error from the provider * @returns A standardized ModelError */ protected transformError(error: unknown): ModelError; /** * Create a ModelError with appropriate error code. */ private createModelError; /** * Determine the appropriate error code based on error characteristics. */ private determineErrorCode; /** * Extract the offending parameter name from a param-naming 400 (#4069). * * Returns the param only when the error is a 400 AND carries a non-empty `param` * field (the OpenAI SDK / OpenAI-compatible gateways set this on a rejected * parameter; the OpenAI adapter threads it onto the classification probe). * Returns undefined otherwise, so non-400s and param-less 400s are untouched. */ private extractErrorParam; /** * (#2540 PR 8) Detect model-retirement errors. Distinct from transient * 502/503: 404 + vendor messages indicating the model id is gone. */ private isModelNotFoundError; /** * Check if error indicates a timeout. */ private isTimeoutError; /** * Check if error indicates model unavailability. */ private isUnavailableError; } /** * nexus-agents/adapters - Streaming Types and Core Utilities * * Shared types, errors, and core streaming primitives used by both * streaming.ts and stream-operators.ts to avoid circular dependencies. */ /** * Error thrown when a stream operation fails. */ declare class StreamError extends NexusError { constructor(message: string, options?: { cause?: Error; context?: Record; }); } /** * Error thrown when a stream is cancelled. */ declare class StreamCancelledError extends NexusError { constructor(reason?: string); } /** * State of a stream controller. */ type StreamState = 'idle' | 'streaming' | 'paused' | 'cancelled' | 'completed' | 'error'; /** * Options for creating a stream. */ interface CreateStreamOptions { /** AbortSignal for cancellation support */ signal?: AbortSignal; /** Maximum buffer size for backpressure (default: 100) */ maxBufferSize?: number; } /** * Controller for managing stream lifecycle. * Provides push/complete/error methods and cancellation support. */ declare class StreamController { private readonly chunks; private readonly waiters; private _state; private _error; private readonly maxBufferSize; private readonly abortHandler; private readonly abortSignal; /** * Creates a new StreamController. * @param options - Stream creation options */ constructor(options?: CreateStreamOptions); /** * Current state of the stream. */ get state(): StreamState; /** * Whether the stream is still active (can receive chunks). */ get isActive(): boolean; /** * Current buffer size. */ get bufferSize(): number; /** * Push a chunk to the stream. * @param chunk - The chunk to push * @returns Result indicating success or backpressure */ push(chunk: T): Result; /** * Complete the stream successfully. */ complete(): void; /** * Complete the stream with an error. * @param error - The error that occurred */ error(error: Error): void; /** * Cancel the stream. * @param reason - Optional reason for cancellation */ cancel(reason?: string): void; /** * Get the AsyncIterable for consuming the stream. */ getIterable(): AsyncIterable; private nextChunk; private removeAbortListener; private resolveAllWaiters; private rejectAllWaiters; } /** * Creates a controllable stream. * @param options - Stream creation options * @returns Tuple of [controller, iterable] */ declare function createStream(options?: CreateStreamOptions): [StreamController, AsyncIterable]; /** * nexus-agents/adapters - Stream Operators Helpers * * Helper functions for stream operations extracted for maintainability. */ /** * Takes the first N chunks from a stream. * @param stream - The source stream * @param count - Number of chunks to take * @param options - Options including optional AbortSignal * @returns Stream of first N chunks */ declare function take(stream: AsyncIterable, count: number, options?: { signal?: AbortSignal; }): AsyncIterable; /** * Skips the first N chunks from a stream. * @param stream - The source stream * @param count - Number of chunks to skip * @param options - Options including optional AbortSignal * @returns Stream with first N chunks skipped */ declare function skip(stream: AsyncIterable, count: number, options?: { signal?: AbortSignal; }): AsyncIterable; /** * Concatenates multiple streams sequentially. * @param streams - The streams to concatenate * @param options - Options including optional AbortSignal * @returns Concatenated stream */ declare function concatStreams(streams: AsyncIterable[], options?: { signal?: AbortSignal; }): AsyncIterable; /** * Creates a stream from an array of values. * @param values - The values to stream * @param options - Options including optional delay between chunks * @returns Stream of values */ declare function fromArray(values: T[], options?: { delayMs?: number; signal?: AbortSignal; }): AsyncIterable; /** * Taps into a stream without modifying it (for side effects like logging). * @param stream - The source stream * @param fn - Side effect function called for each chunk * @param options - Options including optional AbortSignal * @returns Original stream unchanged */ declare function tapStream(stream: AsyncIterable, fn: (chunk: T, index: number) => void | Promise, options?: { signal?: AbortSignal; }): AsyncIterable; /** * Reduces a stream to a single value. * @param stream - The source stream * @param reducer - Reducer function * @param initialValue - Initial accumulator value * @param options - Options including optional AbortSignal * @returns Result containing the final value or error */ declare function reduceStream(stream: AsyncIterable, reducer: (accumulator: U, chunk: T, index: number) => U | Promise, initialValue: U, options?: { signal?: AbortSignal; }): Promise>; /** * nexus-agents/adapters - Stream Operators * * Stream transformation operators for AsyncIterables. * Provides filter, map, merge, concat, buffer, and other stream operations. */ /** * Transforms stream chunks using a mapping function. * @param stream - The source stream * @param fn - Transformation function * @param options - Options including optional AbortSignal * @returns Transformed stream */ declare function transformStream(stream: AsyncIterable, fn: (chunk: T, index: number) => U | Promise, options?: { signal?: AbortSignal; }): AsyncIterable; /** * Merges multiple streams into a single stream. * Chunks are yielded as they arrive from any source. * @param streams - The streams to merge * @param options - Options including optional AbortSignal * @returns Merged stream */ declare function mergeStreams(streams: AsyncIterable[], options?: { signal?: AbortSignal; }): AsyncIterable; /** * Takes chunks from a stream until a predicate returns true. * @param stream - The source stream * @param predicate - Function that returns true to stop taking * @param options - Options including whether to include the matching chunk * @returns Stream of chunks up to (and optionally including) the match */ declare function takeUntil(stream: AsyncIterable, predicate: (chunk: T, index: number) => boolean | Promise, options?: { signal?: AbortSignal; inclusive?: boolean; }): AsyncIterable; /** * Filters stream chunks based on a predicate. * @param stream - The source stream * @param predicate - Function that returns true to keep the chunk * @param options - Options including optional AbortSignal * @returns Filtered stream */ declare function filterStream(stream: AsyncIterable, predicate: (chunk: T, index: number) => boolean | Promise, options?: { signal?: AbortSignal; }): AsyncIterable; /** * Adds a timeout to a stream. If no chunk is received within the timeout, * the stream throws a TimeoutError. * @param stream - The source stream * @param timeoutMs - Timeout in milliseconds * @param options - Options including optional AbortSignal * @returns Stream with timeout applied */ declare function withTimeout(stream: AsyncIterable, timeoutMs: number, options?: { signal?: AbortSignal; }): AsyncIterable; /** * Buffers stream chunks into groups of a specified size. * @param stream - The source stream * @param size - Buffer size * @param options - Options including optional AbortSignal * @returns Stream of chunk arrays */ declare function bufferStream(stream: AsyncIterable, size: number, options?: { signal?: AbortSignal; }): AsyncIterable; /** * nexus-agents/adapters - Streaming Utilities * * AsyncIterator-based streaming utilities for model responses. * Provides stream creation, backpressure handling, cancellation support, * and chunk collection helpers. * * For stream transformation operators (map, filter, merge, etc.), * see ./stream-operators.ts */ /** * Default cap on collected chunks — prevents unbounded memory growth when * callers forget to pass `maxChunks`. Callers that genuinely need no cap * must opt in explicitly with `{ maxChunks: Infinity }`. (#1913 Class F) */ declare const DEFAULT_COLLECT_STREAM_MAX_CHUNKS = 100000; /** * Collects all chunks from a stream into an array. * * @param stream - The stream to collect * @param options - Options including optional AbortSignal. * `maxChunks` defaults to {@link DEFAULT_COLLECT_STREAM_MAX_CHUNKS} to * prevent unbounded memory growth on forgotten limits. Pass * `Infinity` explicitly for truly unbounded collection. * @returns Result containing collected chunks or error */ declare function collectStream(stream: AsyncIterable, options?: { signal?: AbortSignal; maxChunks?: number; }): Promise>; /** * nexus-agents/adapters - Claude Adapter Types * * Type definitions and constants for the Claude/Anthropic adapter. * * @module adapters/claude-adapter-types */ /** * Supported Claude model identifiers. * * Derived from `config/in-tree-data.ts` via `getCliModelName()` (which reads * the ModelRegistry — see `config/model-registry.ts`). Do not hardcode * model-version strings here; update the registry. */ declare const CLAUDE_MODELS: { readonly OPUS_4: string; readonly SONNET_4: string; readonly HAIKU_4: string; }; /** * Legacy version-suffix aliases mapped to the current registry cliModelName. * * Values come from `CLAUDE_MODELS` so they stay in sync with the canonical * registry. Add legacy entries here, never the version strings themselves. */ declare const CLAUDE_MODEL_ALIASES: Record; /** * Configuration specific to ClaudeAdapter. */ interface ClaudeAdapterConfig { /** Model ID (e.g., 'claude-sonnet-4' or full model identifier) */ modelId: string; /** API key for Anthropic API (required) */ apiKey: string; /** Base URL for API (optional, defaults to Anthropic's API) */ baseUrl?: string; /** Request timeout in milliseconds (optional) */ timeout?: number; /** Maximum retries for failed requests (optional) */ maxRetries?: number; } /** * nexus-agents/adapters - Claude/Anthropic Model Adapter * * Adapter for Anthropic's Claude models (claude-opus-4, claude-sonnet-4, claude-haiku-3). * Implements the IModelAdapter interface with streaming support, rate limiting, * and proper error handling. * * Verified 2026-01-03: @anthropic-ai/sdk@0.71.2 is current stable * (Source: npm registry) */ /** * Claude/Anthropic model adapter. * * Provides a unified interface for interacting with Anthropic's Claude models. * Supports completion, streaming, tool use, and vision capabilities. * * @example * ```typescript * const adapter = new ClaudeAdapter({ * modelId: 'claude-sonnet-4', * apiKey: process.env.ANTHROPIC_API_KEY, * }); * * const result = await adapter.complete({ * messages: [{ role: 'user', content: 'Hello!' }], * maxTokens: 1024, * }); * * if (result.ok) { * console.log(result.value.content); * } * ``` */ declare class ClaudeAdapter extends BaseAdapter { private readonly client; private readonly resolvedModelId; /** * Creates a new ClaudeAdapter instance. * * @param config - Claude adapter configuration * @throws {ConfigError} If API key is missing */ constructor(config: ClaudeAdapterConfig); /** * Validates adapter configuration. * Extends base validation with Claude-specific checks. */ validateConfig(): Result; /** * Send a completion request to Claude. * * @param request - The completion request * @returns Result with response or ModelError */ complete(request: CompletionRequest): Promise>; /** * Stream a completion request from Claude. * * @param request - The completion request * @yields StreamChunk objects as they arrive */ stream(request: CompletionRequest): AsyncIterable; /** * Count tokens in text using Claude-specific estimation. * * Claude uses a custom tokenizer. This provides a more accurate estimate * than the base adapter's generic calculation. * * @param text - Text to count tokens for * @returns Approximate token count */ countTokens(text: string): Promise; /** * Executes the completion request against the Anthropic API. */ private executeCompletion; /** * Executes streaming completion and pushes chunks to the controller. */ private executeStream; /** * Builds Anthropic API request parameters from our CompletionRequest. */ private buildRequestParams; /** * Applies optional parameters to the request params. * * @returns the params the seam dropped (#4069) — surfaced as response warnings. */ private applyOptionalParams; /** * Maps Anthropic API response to our CompletionResponse format. */ private mapResponse; /** Usage for a `message_start` chunk, omitted when the vendor sent none (#4835). */ private static usageFrom; /** * Maps Anthropic stream events to our StreamChunk format. */ private mapStreamEvent; /** * (#2540) List models the Anthropic API currently exposes. * Wraps `client.models.list()`. Cached for 5 min, in-flight promise * shared across concurrent callers, throws on non-2xx so the * harness-side identity resolver knows to fall back. */ listModels(): Promise; private modelsCache; private modelsInFlight; private fetchModels; } /** * Creates a ClaudeAdapter with the specified configuration. * Factory function for cleaner API. * * @param config - Claude adapter configuration * @returns A configured ClaudeAdapter instance * * @example * ```typescript * const adapter = createClaudeAdapter({ * modelId: 'claude-sonnet-4', * apiKey: process.env.ANTHROPIC_API_KEY!, * }); * ``` */ declare function createClaudeAdapter(config: ClaudeAdapterConfig): ClaudeAdapter; /** * nexus-agents/adapters - OpenAI Type Helpers * * Type definitions and constants for the OpenAI direct-API SDK adapter. * * **Architectural boundary (#2200 Child 3):** these constants do NOT live * in `config/in-tree-data.ts`. The canonical registry's `cliName` * dimension targets CLI tools (`claude` / `gemini` / `codex` / `opencode`) * — there is no `openai` CLI binary. Adding `'openai'` to the CLI_NAMES * enum would force a fifth case in 4+ exhaustive switches across the * codebase, violating the semantic of "CLI tool name." * * The OpenAI direct adapter is conceptually different from CLI adapters: * it talks to the OpenAI HTTPS API directly, not via a subprocess CLI. * Its model identifiers are OpenAI's own (`gpt-4o-2024-11-20`, * `gpt-3.5-turbo-0125`, etc.) — these are upstream API constants, not * versions WE chose. They drift only when OpenAI ships new dated releases. * * This file is the single source of truth for OpenAI direct-API model * identifiers. The model-string drift fitness-guard (#2199) treats it as * a documented architectural exception in the allowlist. */ /** * Supported OpenAI direct-API model identifiers (OpenAI's own dated names). * * GPT_5_2_CODEX derives from the canonical registry (codex-5.2's cliModelName) * because it overlaps with the Codex CLI; the rest are pure-API constants. * Since #5091 that entry points at `gpt-5.3-codex-spark` (codex no longer * serves gpt-5.2-codex), so the key's name lags its value; renaming the key is * a public-API change and is tracked separately. */ declare const OPENAI_MODELS: { readonly GPT_5_2: "gpt-5.2"; readonly GPT_5_2_INSTANT: "gpt-5.2-chat-latest"; readonly GPT_5_2_PRO: "gpt-5.2-pro"; /** * Registry-derived: resolves to `codex-5.2`'s `cliModelName`, which since * #5091 is `gpt-5.3-codex-spark`, not a "5.2" model. The key name lags its * value; renaming it is a public-API change tracked in #5489. */ readonly GPT_5_2_CODEX: string; readonly GPT_4O: "gpt-4o-2024-11-20"; readonly GPT_4O_MINI: "gpt-4o-mini-2024-07-18"; readonly GPT_4_TURBO: "gpt-4-turbo-2024-04-09"; readonly GPT_35_TURBO: "gpt-3.5-turbo-0125"; }; /** * User-friendly OpenAI aliases → dated model identifiers. * * Identity-only mappings (e.g., `'gpt-5.2-pro' → 'gpt-5.2-pro'`) were * removed in #2200 Child 3 — `resolveModelId` already passes unknown ids * through unchanged via `?? modelId`. Only entries that translate a * shorthand into a dated version remain. */ declare const OPENAI_MODEL_ALIASES: Record; /** * Configuration specific to OpenAIAdapter. */ interface OpenAIAdapterConfig { /** Model ID (e.g., 'gpt-4o' or full model identifier) */ modelId: string; /** API key for OpenAI API (required) */ apiKey: string; /** Base URL for API (optional, defaults to OpenAI's API) */ baseUrl?: string; /** Request timeout in milliseconds (optional) */ timeout?: number; /** Maximum retries for failed requests (optional) */ maxRetries?: number; /** Organization ID (optional) */ organization?: string; } /** * nexus-agents/adapters - OpenAI Model Adapter * * Adapter for OpenAI models (GPT-4o, GPT-4-turbo, GPT-3.5-turbo). * Implements the IModelAdapter interface with streaming support, rate limiting, * and proper error handling. * * Verified 2026-01-03: openai@6.15.0 is current stable * (Source: npm registry) */ declare class OpenAIAdapter extends BaseAdapter { private readonly client; private readonly resolvedModelId; /** * Creates a new OpenAIAdapter instance. * * @param config - OpenAI adapter configuration * @throws {ConfigError} If API key is missing */ constructor(config: OpenAIAdapterConfig); /** * Creates the OpenAI client with configuration. */ private createClient; /** * Validates adapter configuration. * Extends base validation with OpenAI-specific checks. */ validateConfig(): Result; /** * Send a completion request to OpenAI. * * @param request - The completion request * @returns Result with response or ModelError */ complete(request: CompletionRequest): Promise>; /** * Surface an OpenAI / OpenAI-compatible gateway's REAL HTTP status + response * body in the error (#4047). The OpenAI SDK's default message collapses a * gateway rejection to e.g. `"400 status code (no body)"`, which hides WHY a * litellm-style gateway rejected a request — exactly the wall hit when * diagnosing degraded voter panels on a custom gateway. We re-message with the * status/type/code/param/request-id/body. Error-code routing is unchanged: we * classify on the ORIGINAL signal (`status`/`code`/`message`) via a clean probe * error, so the diagnostic `request_id`/`body` can't pollute the message- * substring classifier, then re-message the result with the full detail. * Applies to direct OpenAI and the compat gateway alike. */ protected transformError(error: unknown): ModelError; /** * Stream a completion request from OpenAI. * * @param request - The completion request * @yields StreamChunk objects as they arrive */ stream(request: CompletionRequest): AsyncIterable; /** * Count tokens in text using OpenAI-specific estimation. * * @param text - Text to count tokens for * @returns Approximate token count */ countTokens(text: string): Promise; /** * Executes the completion request against the OpenAI API. */ private executeCompletion; /** * Executes streaming completion and pushes chunks to the controller. */ private executeStream; /** * Builds OpenAI API request parameters from our CompletionRequest. */ private buildRequestParams; /** * Builds the messages array for the request. */ private buildMessages; /** * Adds optional parameters to the request. */ private addOptionalParams; /** * Adds response format to the request if specified. */ private addResponseFormat; /** * Maps OpenAI API response to our CompletionResponse format. */ private mapResponse; /** * Creates an empty response when no choices are returned. */ private createEmptyResponse; /** * (#2529) List models served by this OpenAI-compatible endpoint. * * Wraps `GET /v1/models`. Result is cached for `LIST_MODELS_TTL_MS` * so identity resolution doesn't round-trip on every adapter. * Concurrent callers share the in-flight promise. * * Throws on non-2xx so the harness-side identity resolver knows to * fall back to modelId parsing — silent empty-list returns would be * indistinguishable from "this gateway has no models", which a * misconfigured endpoint shouldn't be allowed to claim. */ listModels(): Promise; private modelsCache; private modelsInFlight; private fetchModels; } /** * Creates an OpenAIAdapter with the specified configuration. * Factory function for cleaner API. * * @param config - OpenAI adapter configuration * @returns A configured OpenAIAdapter instance * * @example * ```typescript * const adapter = createOpenAIAdapter({ * modelId: 'gpt-4o', * apiKey: process.env.OPENAI_API_KEY!, * }); * ``` */ declare function createOpenAIAdapter(config: OpenAIAdapterConfig): OpenAIAdapter; /** * nexus-agents/adapters - Ollama Model Adapter * * Adapter for local Ollama models (llama3, mistral, codellama, etc.). * Verified 2026-01-03: ollama@0.6.3 is current stable (Source: npm registry) */ /** Popular Ollama model identifiers. */ declare const OLLAMA_MODELS: { readonly LLAMA3_8B: "llama3:8b"; readonly LLAMA3_70B: "llama3:70b"; readonly LLAMA3_1_8B: "llama3.1:8b"; readonly LLAMA3_2_3B: "llama3.2:3b"; readonly MISTRAL: "mistral"; readonly MISTRAL_NEMO: "mistral-nemo"; readonly CODELLAMA: "codellama"; readonly CODELLAMA_34B: "codellama:34b"; readonly DEEPSEEK_CODER: "deepseek-coder"; readonly QWEN2_5_CODER: "qwen2.5-coder"; readonly PHI3: "phi3"; readonly GEMMA2: "gemma2"; }; /** Configuration specific to OllamaAdapter. */ interface OllamaAdapterConfig { modelId: string; baseUrl?: string; timeout?: number; maxRetries?: number; headers?: Record; } /** Ollama model adapter for local model inference. */ declare class OllamaAdapter extends BaseAdapter { private readonly client; constructor(config: OllamaAdapterConfig); validateConfig(): Result; complete(request: CompletionRequest): Promise>; stream(request: CompletionRequest): AsyncIterable; countTokens(text: string): Promise; private executeStream; private buildOptions; private applyFormatAndTools; private buildRequestParams; private mapResponse; private calcUsage; } /** Creates an OllamaAdapter with the specified configuration. */ declare function createOllamaAdapter(config: OllamaAdapterConfig): OllamaAdapter; /** * nexus-agents/adapters - Gemini Type Utilities * * Type mappings and helper functions for the Gemini adapter. */ /** * Supported Gemini model identifiers. * * Current models (2.5+ and 3.x) derive from `config/in-tree-data.ts` * (single source of truth — #2200 Child 2). Legacy 1.5 / 2.0 strings remain * as constants for backward compat with external consumers; they are not in * the canonical registry because Google deprecated those generations * upstream in 2025. */ declare const GEMINI_MODELS: { readonly PRO_2_5: string; readonly FLASH_2_5: string; readonly FLASH_2_0: "gemini-2.0-flash"; readonly PRO_1_5: "gemini-1.5-pro"; readonly FLASH_1_5: "gemini-1.5-flash"; }; /** * Legacy aliases for Gemini models not in the canonical registry. * * 2.5 / 3.x aliases are NOT in this map — they resolve via the canonical * registry (cliModelName / cliAlias / aliases[]). See `resolveModelId`. * Only generations Google has deprecated upstream live here, kept for * backward compat with users who hardcoded these strings. */ declare const GEMINI_MODEL_ALIASES: Record; /** * Configuration specific to GeminiAdapter. */ interface GeminiAdapterConfig { /** Model ID (e.g., 'gemini-2.5-flash' or full model identifier) */ modelId: string; /** API key for Google AI API (required) */ apiKey: string; /** Request timeout in milliseconds (optional) */ timeout?: number; /** Maximum retries for failed requests (optional) */ maxRetries?: number; } /** * nexus-agents/adapters - Gemini/Google AI Model Adapter * * Adapter for Google's Gemini models (gemini-2.5-pro, gemini-2.5-flash, gemini-2.0-flash). * Implements the IModelAdapter interface with streaming support, tool calling, * and proper error handling. * * Verified 2026-07-18: @google/genai@2.12.0 is current stable (#4045). * 2.x breaking changes are Interactions-API-only; the stable * models.generateContent* surface used here is unaffected. */ /** * Gemini/Google AI model adapter. * * Provides a unified interface for interacting with Google's Gemini models. * Supports completion, streaming, tool use, and vision capabilities. * * @example * ```typescript * const adapter = new GeminiAdapter({ * modelId: 'gemini-2.5-flash', * apiKey: process.env.GOOGLE_AI_API_KEY, * }); * * const result = await adapter.complete({ * messages: [{ role: 'user', content: 'Hello!' }], * maxTokens: 1024, * }); * * if (result.ok) { * console.log(result.value.content); * } * ``` */ declare class GeminiAdapter extends BaseAdapter { private readonly client; private readonly resolvedModelId; /** * Creates a new GeminiAdapter instance. * * @param config - Gemini adapter configuration * @throws {ConfigError} If API key is missing */ constructor(config: GeminiAdapterConfig); /** * Validates adapter configuration. * Extends base validation with Gemini-specific checks. */ validateConfig(): Result; /** * Send a completion request to Gemini. * * @param request - The completion request * @returns Result with response or ModelError */ complete(request: CompletionRequest): Promise>; /** * Stream a completion request from Gemini. * * @param request - The completion request * @yields StreamChunk objects as they arrive */ stream(request: CompletionRequest): AsyncIterable; /** * Count tokens in text using Gemini-specific estimation. * * @param text - Text to count tokens for * @returns Approximate token count */ countTokens(text: string): Promise; /** * Executes the completion request against the Google AI API. */ private executeCompletion; /** Stream controller type for executeStream. */ private readonly streamControllerType; /** * Emits the end-of-message events to the stream controller. */ private emitStreamEnd; /** * Executes streaming completion and pushes chunks to the controller. */ private executeStream; /** * Builds generation config from request parameters. */ private buildGenerationConfig; /** * Builds Google AI API request parameters from our CompletionRequest. */ private buildRequestParams; /** * Generates a unique tool ID. */ private generateToolId; /** * Extracts content blocks from the response. */ private extractContentBlocks; /** * Maps Google AI API response to our CompletionResponse format. */ private mapResponse; /** * (#2540) List Gemini models exposed by the configured API key. * Wraps `client.models.list()` (returns a Pager). 5-min cache, * concurrent-caller promise sharing. */ listModels(): Promise; private modelsCache; private modelsInFlight; private fetchModels; } /** * Creates a GeminiAdapter with the specified configuration. * Factory function for cleaner API. * * @param config - Gemini adapter configuration * @returns A configured GeminiAdapter instance * * @example * ```typescript * const adapter = createGeminiAdapter({ * modelId: 'gemini-2.5-flash', * apiKey: process.env.GOOGLE_AI_API_KEY!, * }); * ``` */ declare function createGeminiAdapter(config: GeminiAdapterConfig): GeminiAdapter; /** * nexus-agents/cli-adapters - CLI Detection Cache * * Caches CLI health check results to avoid repeated subprocess calls. * Invalidates on circuit breaker trips or manual invalidation. * * @module cli-adapters/cli-detection-cache * (Source: Issue #165, Proposal adapter-architecture-review.md) */ /** * Cached health result for a CLI. */ interface CliHealthResult { /** Whether the CLI is healthy and available */ readonly healthy: boolean; /** CLI version detected */ readonly version: string; /** Version compatibility status */ readonly versionStatus: VersionStatus; /** When this result was captured */ readonly checkedAt: Date; /** Optional status message */ readonly message?: string | undefined; } /** * Configuration for the CLI detection cache. */ interface CliDetectionCacheConfig { /** Base time-to-live in milliseconds (default: 5 minutes) */ readonly ttlMs: number; /** Enable adaptive TTL based on health history (default: true) */ readonly adaptiveTtl?: boolean | undefined; /** Logger instance */ readonly logger?: ILogger | undefined; } /** * Zod schema for cache configuration validation. */ declare const CliDetectionCacheConfigSchema: z.ZodObject<{ ttlMs: z.ZodDefault; }, z.core.$strip>; /** * Default cache configuration. */ declare const DEFAULT_CACHE_CONFIG: CliDetectionCacheConfig; /** * Interface for CLI detection cache. * Allows dependency injection for testing. */ interface ICliDetectionCache { /** Get cached health result for a CLI */ get(cli: CliName): CliHealthResult | undefined; /** Set health result for a CLI */ set(cli: CliName, result: CliHealthResult): void; /** Check if cache entry is stale */ isStale(cli: CliName): boolean; /** Invalidate cache for a specific CLI or all CLIs */ invalidate(cli?: CliName): void; /** Get all cached results */ getAll(): ReadonlyMap; /** Get cache statistics */ getStats(): CacheStats; /** Get effective TTL for a CLI (accounts for adaptive adjustments) */ getEffectiveTtl(cli: CliName): number; } /** * Cache statistics for observability. */ interface CacheStats { /** Number of cached entries */ readonly size: number; /** Cache hits since last reset */ readonly hits: number; /** Cache misses since last reset */ readonly misses: number; /** Hit rate (0-1) */ readonly hitRate: number; /** When stats were last reset */ readonly lastReset: Date; } /** * CLI detection cache implementation. * Thread-safe for Node.js single-threaded execution. */ declare class CliDetectionCache implements ICliDetectionCache { private readonly config; private readonly logger; private readonly cache; /** Consecutive same-health-status count per CLI (for adaptive TTL). */ private readonly streaks; private hits; private misses; private lastReset; constructor(config?: Partial); get(cli: CliName): CliHealthResult | undefined; set(cli: CliName, result: CliHealthResult): void; isStale(cli: CliName): boolean; /** Returns the effective TTL for a CLI, applying adaptive multiplier if enabled. */ getEffectiveTtl(cli: CliName): number; private updateStreak; invalidate(cli?: CliName): void; getAll(): ReadonlyMap; getStats(): CacheStats; /** * Resets cache statistics. */ resetStats(): void; /** * Converts HealthStatus to CliHealthResult for caching. */ static fromHealthStatus(status: HealthStatus): CliHealthResult; } /** * Creates a CLI detection cache instance. * * @param config - Optional cache configuration * @returns CLI detection cache * * @example * ```typescript * const cache = createCliDetectionCache({ ttlMs: 60_000 }); // 1 minute TTL * const result = cache.get('claude'); * if (!result) { * const health = await adapter.healthCheck(); * cache.set('claude', CliDetectionCache.fromHealthStatus(health)); * } * ``` */ declare function createCliDetectionCache(config?: Partial): ICliDetectionCache; /** * Circuit breaker states. */ type CircuitState = 'closed' | 'open' | 'half-open'; /** * Categories of failures for circuit breaker decisions. */ type FailureCategory = 'timeout' | 'crash' | 'authentication' | 'rate_limit' | 'connection' | 'unknown'; /** * Configuration options for circuit breaker. */ interface CircuitBreakerConfig { /** Number of failures before opening circuit (default: 5) */ readonly failureThreshold: number; /** Time in ms before attempting recovery (default: 30000) */ readonly resetTimeoutMs: number; /** Successful calls needed in half-open to close (default: 2) */ readonly halfOpenSuccessThreshold: number; /** Whether to count timeouts as failures (default: true) */ readonly countTimeoutsAsFailures: boolean; /** Whether to count auth failures as failures (default: false) */ readonly countAuthFailuresAsFailures: boolean; /** Whether to count rate limit errors as failures (default: false) */ readonly countRateLimitsAsFailures: boolean; /** Maximum number of requests allowed in half-open state (default: 3) */ readonly halfOpenMaxRequests: number; } /** * Circuit breaker state snapshot. */ interface CircuitBreakerSnapshot { /** Current state */ readonly state: CircuitState; /** Total failure count since last closed */ readonly failureCount: number; /** Success count in half-open state */ readonly successCount: number; /** Timestamp of last failure */ readonly lastFailureTime: number | null; /** Timestamp of last state change */ readonly lastStateChange: number; /** Requests in current half-open window */ readonly halfOpenRequests: number; /** Configuration */ readonly config: CircuitBreakerConfig; } /** * Event emitted on circuit state changes. */ interface CircuitStateChangeEvent { /** * Display slot of the guarded arm: identity for a CLI slot, the collapsed * slot for an `api:*` arm (#4392). Always `observedArmDisplaySlot(armId)`; * read {@link armId} to tell an endpoint arm from the slot it displays under. */ readonly cliName: CliName; /** * Arm the breaker guards — a CLI slot, a built-in `api:*` arm or a * registered endpoint arm (#4392). The breaker is the only producer of this * event in tree; a listener that builds one by hand must supply it. */ readonly armId: ObservedArmId; /** Previous state */ readonly previousState: CircuitState; /** New state */ readonly newState: CircuitState; /** Timestamp of change */ readonly timestamp: number; /** Failure count at time of change */ readonly failureCount: number; /** Reason for state change */ readonly reason: string; } /** * Event listener for circuit state changes. */ type CircuitStateChangeListener = (event: CircuitStateChangeEvent) => void; /** * Interface for circuit breaker operations. */ interface ICircuitBreaker { /** * Executes a function with circuit breaker protection. */ execute(fn: () => Promise): Promise>; /** * Gets the current circuit state. */ getState(): CircuitState; /** * Gets a full snapshot of circuit breaker state. */ getSnapshot(): CircuitBreakerSnapshot; /** * Manually resets the circuit breaker to closed state. */ reset(): void; /** * Records a failure manually (for external failure detection). */ recordFailure(category: FailureCategory): void; /** * Records a success manually (for external success detection). */ recordSuccess(): void; } /** * Error codes specific to circuit breaker. */ declare const CircuitErrorCode: { readonly CIRCUIT_OPEN: "CIRCUIT_OPEN"; readonly CIRCUIT_HALF_OPEN_REJECTED: "CIRCUIT_HALF_OPEN_REJECTED"; readonly EXECUTION_FAILED: "EXECUTION_FAILED"; }; type CircuitErrorCode = (typeof CircuitErrorCode)[keyof typeof CircuitErrorCode]; /** * Error thrown when circuit breaker blocks a request. */ declare class CircuitError extends NexusError { readonly circuitErrorCode: CircuitErrorCode; /** Display slot of {@link armId} — never the raw `api:*` id. */ readonly cliName: CliName; /** * Arm whose circuit blocked the request — a CLI slot, a built-in `api:*` arm * or a registered endpoint arm (#4392). Defaults to `cliName` when the * constructor is called with the pre-#4392 option shape. */ readonly armId: ObservedArmId; readonly circuitState: CircuitState; readonly failureCategory?: FailureCategory; constructor(message: string, options: { circuitErrorCode: CircuitErrorCode; /** Display slot; the breaker passes `observedArmDisplaySlot(armId)`. */ cliName: CliName; /** The guarded arm (#4392). Optional so the pre-#4392 option shape still compiles; defaults to `cliName`. */ armId?: ObservedArmId; circuitState: CircuitState; failureCategory?: FailureCategory; cause?: Error; }); } /** * nexus-agents/cli-adapters - Circuit Breaker Implementation * * Implements the circuit breaker pattern to handle CLI failures gracefully * and prevent cascade failures in the multi-CLI mesh. * * (Source: Issue #81 - Circuit breaker for CLI failures) * (Source: Martin Fowler's Circuit Breaker pattern) */ /** * Circuit breaker implementation for CLI adapters. * * Provides protection against cascading failures by: * 1. Tracking failure counts * 2. Opening circuit when threshold exceeded * 3. Allowing gradual recovery through half-open state */ declare class CliCircuitBreaker implements ICircuitBreaker { private readonly armId; private readonly config; private state; private failureCount; private successCount; private lastFailureTime; private lastStateChange; private halfOpenRequests; private readonly listeners; /** Display slot of {@link armId}; what `cliName` fields on events and errors carry. */ private readonly cliName; constructor(armId: ObservedArmId, config?: CircuitBreakerConfig); /** * Executes a function with circuit breaker protection. */ execute(fn: () => Promise): Promise>; getState(): CircuitState; getSnapshot(): CircuitBreakerSnapshot; reset(): void; recordFailure(category: FailureCategory): void; recordSuccess(): void; addStateChangeListener(listener: CircuitStateChangeListener): void; removeStateChangeListener(listener: CircuitStateChangeListener): void; private canExecute; private checkStateTransition; private onSuccess; private onFailure; private transitionTo; private emitStateChange; private shouldCountFailure; private createExecutionError; } /** * Registry for managing per-arm circuit breakers. * * Keyed by {@link ObservedArmId} since #4392 — a published `RoutingArmId` or a * registered `EndpointArmId`: a CLI slot and an `api:*` arm are distinct keys, * so an endpoint opening never speaks for the CLI slot it displays under. The `*Arm*` methods are the source of truth over that map; * the older `CliName`-typed methods keep their signatures and are FILTERED * VIEWS of the same map, restricted to the four CLI slots — an `api:*` arm * never appears in `getHealthyClis()` / `getUnhealthyClis()` / * `getAllSnapshots()`, only in their `*Arms` siblings (#6290 panel; the * narrow methods are removed in 9.0, #6291). */ declare class CircuitBreakerRegistry { private readonly defaultConfig; private readonly breakers; private readonly globalListeners; constructor(defaultConfig?: Partial); /** Breaker for any routing arm, created on first request (#4392). */ getArmBreaker(armId: ObservedArmId, config?: Partial): CliCircuitBreaker; /** CLI-slot view of {@link getArmBreaker}: the same breaker, same map. */ getBreaker(cliName: CliName, config?: Partial): CliCircuitBreaker; isArmOpen(armId: ObservedArmId): boolean; /** CLI-slot view of {@link isArmOpen}. */ isOpen(cliName: CliName): boolean; /** Snapshot of every arm the registry holds, CLI slots and `api:*` arms alike. */ getAllArmSnapshots(): Map; /** CLI-slot view of {@link getAllArmSnapshots}: `api:*` arms are filtered out. */ getAllSnapshots(): Map; resetAll(): void; resetArm(armId: ObservedArmId): void; /** CLI-slot view of {@link resetArm}. */ reset(cliName: CliName): void; addGlobalStateChangeListener(listener: CircuitStateChangeListener): void; removeGlobalStateChangeListener(listener: CircuitStateChangeListener): void; /** Every arm whose circuit is closed. Empty registry: `[]` — nothing is known healthy. */ getHealthyArms(): ObservedArmId[]; /** CLI-slot view of {@link getHealthyArms}: `api:*` arms are filtered out. */ getHealthyClis(): CliName[]; /** Every arm whose circuit is open or half-open. Empty registry: `[]`. */ getUnhealthyArms(): ObservedArmId[]; /** CLI-slot view of {@link getUnhealthyArms}: `api:*` arms are filtered out. */ getUnhealthyClis(): CliName[]; } /** * Health states for the adapter. * - healthy: adapter detected and operational * - degraded: adapter operational but experienced recent failures * - unavailable: no adapter could be detected */ type AdapterHealthState = 'healthy' | 'degraded' | 'unavailable'; /** * Health information for the current adapter. */ interface AdapterHealthInfo { readonly source: CliName | 'api'; readonly state: AdapterHealthState; readonly selectedAt: Date; readonly failoverCount: number; readonly lastError?: string; } /** * Extension of IModelAdapter with health monitoring and failover. * * Consumers that only need IModelAdapter continue to work unchanged. * Dashboard/monitoring consumers can cast to IResilientAdapter for * health and failover APIs. */ interface IResilientAdapter extends IModelAdapter { /** Current health info (undefined if not yet initialized) */ getHealth(): AdapterHealthInfo | undefined; /** Force re-detection of adapters */ refresh(): Promise; /** Override preferred CLI */ setPreferredCli(cli: CliName | undefined): void; /** Register failover callback */ onFailover(cb: (info: AdapterHealthInfo) => void): () => void; /** * The registry arming this adapter's failover, or `undefined` if none (#4659). * * Read-only on purpose: exposing `attach` here would re-create the "someone * must remember to call it" shape that left the breaker disarmed. Supply it * via {@link ResilientAdapterConfig.circuitBreakerRegistry} instead. This * accessor exists so a caller can VERIFY the adapter is armed. */ getCircuitBreakerRegistry?(): CircuitBreakerRegistry | undefined; /** Cleanup listeners and timers */ dispose(): void; } /** * Unified Adapter Registry — single entry point for all model adapter access. * * Pre-computes task-to-CLI routing from the canonical model registry and * task specialization matrix at creation time. All consumers get adapters * through this registry instead of calling createAutoAdapter/createResilientAdapter * directly. * * Design: * - One IResilientAdapter per CLI (claude/gemini/codex), created lazily on first access * - One "default" adapter for unscoped requests (uses createAutoAdapter priority) * - Task routing is deterministic: category → primary CLI → cached adapter * - Session-scoped: create once at MCP startup, reuse for the session lifetime * * @module adapters/unified-registry * (Source: Issue #1149 — Unified Adapter Registry) * (Source: Issue #1151 — Single adapter entry point) */ /** Configuration for the unified registry. */ interface UnifiedRegistryConfig { /** Logger instance */ readonly logger?: ILogger; /** Default CLI timeout for subprocess calls (ms) */ readonly defaultCliTimeoutMs?: number; } /** Summary of the pre-computed task routing table. */ interface TaskRoutingEntry { readonly category: TaskCategory; readonly primaryCli: CliName; readonly secondaryCli: CliName; readonly primaryModel: string; } /** Snapshot of registry state for observability. */ interface RegistrySnapshot { readonly taskRouting: readonly TaskRoutingEntry[]; /** * CLI-slot view of {@link cachedArms}: the lazily created CLI slots only. * A registered `api:*` arm is never listed here (#6290 panel: this field * keeps its `CliName[]` type; it is retired in 9.0, #6291). */ readonly cachedAdapters: readonly CliName[]; /** Every cached arm: lazily created CLI slots and registered `api:*` endpoint arms (#4392). */ readonly cachedArms: readonly ObservedArmId[]; readonly availableModels: number; } /** * Unified adapter registry. Centralizes all adapter creation and task routing. * * Usage: * ```typescript * const registry = createUnifiedRegistry({ logger }); * const adapter = registry.getAdapter('code_generation'); // → codex adapter * const adapter2 = registry.getAdapterForCli('claude'); // → claude adapter * const adapter3 = registry.getDefault(); // → best available * ``` */ declare class UnifiedAdapterRegistry { private readonly logger; private readonly defaultCliTimeoutMs; /** * Per-arm adapter cache. CLI slots are created lazily by * {@link getAdapterForCli}; `api:*` arms enter only through * {@link registerApiArm} and are never synthesised (#4392). */ private readonly cliAdapters; /** Default adapter for unscoped requests. */ private defaultAdapter; constructor(config?: UnifiedRegistryConfig); /** Logger used by this registry. Exposed so singleton helpers can warn. */ getLogger(): ILogger; /** * Get adapter for a task category. Routing is re-resolved on every read * (#3185) so a post-startup overlay/registry update propagates without a * restart. Falls back to default adapter if category unknown. */ getAdapter(category: TaskCategory): IResilientAdapter; /** * Get adapter for a free-text task description. * Detects category from keywords, falls back to default. */ getAdapterForTask(taskDescription: string): IResilientAdapter; /** * Get adapter pinned to a specific CLI. * Creates and caches one IResilientAdapter per CLI. */ getAdapterForCli(cli: CliName): IResilientAdapter; /** * Get the adapter for a routing arm (#4392). A CLI slot resolves exactly as * {@link getAdapterForCli} (created lazily, cached, armed with the shared * breaker registry). An `api:*` arm resolves to what {@link registerApiArm} * supplied, or `undefined` — never to a CLI slot, and never by creating one. */ getAdapterForArm(arm: ObservedArmId): IResilientAdapter | undefined; /** * Register an `api:*` arm's adapter under its endpoint identity (#4392). * Accepts a built-in `ApiArmId` or a dynamic `EndpointArmId`; the id is * re-validated at runtime because the `EndpointArmId` type admits any `api:` * string, so a cast from an unvalidated name is exactly what this refuses. * Registering an id twice replaces (and disposes) the earlier adapter. * CLI-slot behaviour is untouched. A registered endpoint arm is observable * here and in the breaker registry but is NOT a `RoutingArmId`: it cannot * enter outcome records until #6291. A gateway arm registered without a * `NEXUS_GATEWAY_COST` declaration is warned about here, once, at the * moment it becomes routable (#4392 increment 2). */ registerApiArm(arm: EndpointArmId, adapter: IResilientAdapter): void; /** * Get adapter for a model preference string (e.g., "claude-opus-4-6"). * Resolves the model to its CLI via the canonical registry. * Falls back to default adapter if model not recognized. */ getAdapterForModel(modelPreference: string): IResilientAdapter; /** * Get adapter for an expert role (e.g., "code_expert"). * Uses ROLE_TO_TASK_CATEGORY mapping → task specialization → CLI. */ getAdapterForRole(role: string): IResilientAdapter; /** * Get the default adapter (no CLI preference — auto-detection priority). */ getDefault(): IResilientAdapter; /** * Get snapshot of registry state for observability/debugging. Routing is * re-resolved on read (#3185) so the snapshot reflects the live registry. */ getSnapshot(): RegistrySnapshot; /** * Resolve the routing for a specific category. * * Computed on every read (#3185) rather than cached at construction, so a * post-startup model-registry / overlay update (e.g. a default-model change * surfaced via `getDefaultModelForCli`) propagates to routing decisions * without a process restart. The matrix is ~10 categories — the per-read * resolution cost is negligible. */ getRouting(category: TaskCategory): TaskRoutingEntry | undefined; /** * Dispose all cached adapters. */ dispose(): void; /** * Resolve one specialization-matrix row into a routing entry, re-reading the * primary model from the (overlay-aware) model registry each call (#3185). */ private resolveRouting; } /** * Create a new UnifiedAdapterRegistry instance. * For most uses, prefer `getGlobalRegistry()` instead. */ declare function createUnifiedRegistry(config?: UnifiedRegistryConfig): UnifiedAdapterRegistry; /** * Thrown by {@link getGlobalRegistry} when a non-empty config arrives after * the singleton exists (#5211). The registry has no way to apply it — the * logger and `defaultCliTimeoutMs` are fixed at construction — so until this * error existed the config was logged at `warn` and dropped, and the caller * went on with a registry built from someone else's settings. A config that is * accepted and ignored is an instrument that misreports what it was given. * * The check is on presence, not on equality with the live config: the registry * does not keep the config it was built from, and a caller re-supplying the * same values is still a caller that believes it configured something. */ declare class RegistryAlreadyInitializedError extends ConfigError { constructor(providedKeys: readonly string[]); } /** * Get the global singleton registry. * Creates it on first access with default config. * * If the singleton already exists and a non-empty config is supplied, this * throws {@link RegistryAlreadyInitializedError} — the config cannot be * applied, and returning the existing instance would silently hand the caller * a registry configured by whoever ran first (#5211). Omitting the config, or * passing an empty object, returns the existing instance as before. */ declare function getGlobalRegistry(config?: UnifiedRegistryConfig): UnifiedAdapterRegistry; /** Reset the global registry (for testing). */ declare function resetGlobalRegistry(): void; /** * nexus-agents/adapters/sdk - Shared Types * * Type definitions for AI SDK adapter layer. * * @module adapters/sdk/types * (Source: Issue #1123 — AI SDK provider layer) */ /** * Supported AI SDK provider identifiers. * * `custom-openai` is for OpenAI-compatible gateways (multi-vendor proxies, * self-hosted LLM servers, corporate model gateways) — uses the same * @ai-sdk/openai package but with a configurable `baseURL`. */ type SdkProviderId = 'anthropic' | 'openai' | 'google' | 'custom-openai'; /** * Configuration for creating an AI SDK adapter. */ interface SdkAdapterConfig { /** Provider identifier */ providerId: SdkProviderId; /** Model to use (e.g., 'claude-sonnet-4-6', 'gpt-4o') */ modelId: string; /** API key (falls back to environment variable) */ apiKey?: string; /** * Base URL for OpenAI-compatible gateways. Required when * `providerId === 'custom-openai'`, ignored otherwise. Falls back to * the `NEXUS_OPENAI_COMPAT_URL` environment variable, or its deprecated * alias `NEXUS_CUSTOM_API_BASE_URL` (#4392 increment 3). */ baseUrl?: string; /** Request timeout in milliseconds */ timeout?: number; /** Maximum retries on transient failures */ maxRetries?: number; } /** * Maps provider IDs to their environment variable names. * * The three vendor entries are current. The `custom-openai` entry is kept at * its old value so existing readers of this table keep working, but the name * it holds is deprecated — see the entry's own note. */ declare const PROVIDER_ENV_KEYS: Record; /** * nexus-agents/adapters/sdk - Base SDK Adapter * * Implements IModelAdapter using the Vercel AI SDK's generateText/streamText * APIs. Provides a unified adapter for any AI SDK-supported provider. * * @module adapters/sdk/sdk-adapter * (Source: Issue #1123 — AI SDK provider layer) */ /** * AI SDK adapter implementing IModelAdapter. * * Uses Vercel AI SDK (npm: ai) for model interaction instead of * CLI subprocess spawning. Supports any provider that has an * `@ai-sdk/*` package. */ declare class SdkAdapter extends BaseAdapter { private readonly sdkProviderId; private model; private sdkFunctions; private readonly sdkConfig; /** Validated base URL for custom-openai provider; undefined for built-ins. */ private readonly customBaseUrl; /** Inflight init promise for coalescing concurrent calls (Issue #1438). */ private initPromise; /** * Cached result of the DNS-resolve-time SSRF check for custom-openai * (#3426). Resolved once on first init so we don't re-resolve the gateway * hostname on every request. `undefined` until the check has run. */ private resolveSsrfChecked; constructor(config: SdkAdapterConfig, logger?: ILogger); /** * Lazily initialize the AI SDK model and functions. * This allows the adapter to be created without the AI SDK installed, * failing only when actually used. */ private ensureInitialized; private doInitialize; /** * For custom-openai only: run the DNS-resolve-time SSRF check exactly once * and throw if the gateway hostname resolves to a private address (#3426). * Cached via `resolveSsrfChecked` so the hostname is not re-resolved on * every request. No-op for non-custom providers (built-in endpoints are * trusted) and when no custom base URL is configured. */ private ensureCustomHostResolvesPublic; /** * Loads the provider-specific AI SDK module. * * Each @ai-sdk/* package exports a factory function (e.g., createAnthropic) * that returns a callable provider instance. We use extractProviderFactory() * to validate the export exists at runtime, since these are optional peer deps. */ private loadProvider; /** * Maps our CompletionRequest to AI SDK generateText options. */ private buildSdkOptions; /** * generateText path (text / absent responseFormat) — unchanged behavior. */ private completeText; /** * generateObject path (#3433) — json_object / json_schema responseFormat. * * Uses the AI SDK `jsonSchema` helper to build the schema handle * (permissive `{ type: 'object' }` for json_object), then stringifies the * returned object into a text content block so downstream parsers / * extractTextFromResponse keep working unchanged. */ private completeStructured; complete(request: CompletionRequest): Promise>; stream(request: CompletionRequest): AsyncIterable; /** * Converts a caught error into a Result error with categorized ErrorCode. */ private toErrorResult; } /** * nexus-agents/context - Token Budget Types * * Type definitions for token budget tracking with EMA. * Based on Issue #304 from Agent Improvement Epic #301. * * @module context/token-budget-types */ /** * Error when token budget is exceeded. */ declare class TokenBudgetError extends NexusError { constructor(message: string, options?: { cause?: Error; context?: Record; }); } /** * Token budget enforcement mode. * - 'warn': Log warning but continue (default per DevEx amendment) * - 'hard': Reject request when budget exceeded */ type BudgetEnforcementMode = 'warn' | 'hard'; /** * Configuration for token budget tracking. */ interface TokenBudgetConfig { /** Maximum tokens per task (default: 100000) */ maxTokensPerTask?: number; /** Maximum total tokens per session (default: 1000000) */ maxTokensPerSession?: number; /** EMA alpha for smoothing (0-1, default: 0.3) */ emaAlpha?: number; /** Warning threshold as percentage of budget (default: 75) */ warningThreshold?: number; /** Critical threshold as percentage of budget (default: 90) */ criticalThreshold?: number; /** Enforcement mode (default: 'warn') */ enforcementMode?: BudgetEnforcementMode; } /** * Token usage record for a single operation. */ interface TokenUsageRecord { /** Timestamp of the operation */ timestamp: number; /** Input tokens used */ inputTokens: number; /** Output tokens used */ outputTokens: number; /** Total tokens (input + output) */ totalTokens: number; /** Task or operation identifier */ taskId?: string; } /** * Budget warning levels. */ type BudgetWarningLevel = 'info' | 'warning' | 'critical'; /** * Budget warning event. */ interface BudgetWarning { /** Warning level */ level: BudgetWarningLevel; /** Warning message */ message: string; /** Current usage percentage */ usagePercent: number; /** Tokens used */ tokensUsed: number; /** Budget limit */ budgetLimit: number; /** Whether this is a session or task warning */ scope: 'task' | 'session'; } /** * Budget check result. */ interface BudgetCheckResult { /** Whether the operation is allowed to proceed */ allowed: boolean; /** Estimated tokens for the operation */ estimatedTokens: number; /** Remaining session budget */ remainingSessionBudget: number; /** Remaining task budget */ remainingTaskBudget: number; /** Any warnings generated */ warnings: readonly BudgetWarning[]; /** Error if blocked (only when enforcementMode is 'hard') */ error?: TokenBudgetError; } /** * Budget statistics with EMA. */ interface BudgetStats { /** Total tokens used in session */ sessionTokensUsed: number; /** Current task tokens used */ taskTokensUsed: number; /** EMA of token usage per operation */ tokenUsageEma: number; /** Number of operations tracked */ operationCount: number; /** Session utilization percentage */ sessionUtilizationPercent: number; /** Task utilization percentage */ taskUtilizationPercent: number; /** Predicted tokens for next operation (based on EMA) */ predictedNextTokens: number; } /** * Interface for token budget tracking operations. */ interface ITokenBudgetTracker { /** * Check if an operation is within budget. * @param estimatedTokens - Estimated tokens for the operation * @returns Budget check result with warnings and allowed status */ checkBudget(estimatedTokens: number): BudgetCheckResult; /** * Record actual token usage after an operation. * Updates EMA and session/task totals. * @param usage - Token usage record */ recordUsage(usage: TokenUsageRecord): void; /** * Start a new task context. * Resets task-level budget tracking. * @param taskId - Optional task identifier */ startTask(taskId?: string): void; /** * End the current task context. * @returns Task-level statistics */ endTask(): BudgetStats; /** * Reset session budget (e.g., on session timeout). */ resetSession(): void; /** * Get current budget statistics. */ getStats(): BudgetStats; /** * Get the predicted tokens for the next operation based on EMA. */ predictNextTokens(): number; /** * Update configuration dynamically. * @param config - Partial configuration to update */ updateConfig(config: Partial): void; } /** * nexus-agents/context - Hybrid Memory Backend Types * * Type definitions, interfaces, and schemas for the hybrid memory backend. * * @module context/memory-backend-types */ /** * Importance levels for memory entries. */ declare const MemoryImportance: { readonly LOW: "low"; readonly MEDIUM: "medium"; readonly HIGH: "high"; }; type MemoryImportance = (typeof MemoryImportance)[keyof typeof MemoryImportance]; /** * Metadata associated with a memory entry. */ interface MemoryMetadata { /** Importance level determining storage strategy */ importance: MemoryImportance; /** Optional tags for categorization */ tags?: string[]; /** Time-to-live in milliseconds (optional) */ ttl?: number; } /** * A complete memory entry with all fields. */ interface MemoryEntry { /** Unique key for the memory */ key: string; /** The stored value (JSON-serializable) */ value: unknown; /** Associated metadata */ metadata: MemoryMetadata; /** When the entry was created */ createdAt: Date; /** When the entry was last accessed */ accessedAt: Date; } /** * Error class for memory operations. */ declare class MemoryError extends NexusError { constructor(message: string, options?: Partial; }, 'code'>>); } /** * Interface for memory backend implementations. */ interface IContextMemoryBackend { /** * Store a value with associated metadata. * @param key - Unique key for the memory * @param value - The value to store (must be JSON-serializable) * @param metadata - Associated metadata */ store(key: string, value: unknown, metadata: MemoryMetadata): Promise>; /** * Retrieve a value by key. * @param key - The key to look up * @returns The value or null if not found */ retrieve(key: string): Promise>; /** * Search memories using full-text search. * @param query - Search query string * @param limit - Maximum number of results */ search(query: string, limit: number): Promise>; /** * Remove memories older than the specified date. * @param olderThan - Cutoff date for pruning * @returns Number of entries pruned */ prune(olderThan: Date): Promise>; } /** * The previous name of {@link IContextMemoryBackend}. * * @deprecated Renamed in #5142: this package's context-store contract shared * the name `IMemoryBackend` with `nexus-memory`'s unrelated registry contract * (zero overlapping members), so `implements IMemoryBackend` meant one of two * things depending on the import line. Use `IContextMemoryBackend`. * * An empty EXTENDING interface rather than a `type` alias, deliberately: a * type alias cannot participate in declaration merging, so a consumer * augmenting `IMemoryBackend` would have broken. This form is the same * structural type, assignable both ways, and still augmentable — which is * what makes the rename non-breaking (the majority-bar vote on #5142). * * Removal is tracked and blocked on the next major; see the issue linked * from the #5142 record. Internal code must not import this name — * `no-restricted-imports` in eslint.config.js enforces it. */ interface IMemoryBackend extends IContextMemoryBackend { } /** * nexus-agents/context - Memory Module Types * * Individual memory module interfaces and data types for the MIRIX-style * typed memory system. These are the building blocks for ITypedMemory. * * @module context/memory-module-types * (Source: Issue #101, arXiv:2507.07957 - MIRIX Architecture) */ /** * Core memory stores agent identity, constraints, and role definitions. * This is the most persistent memory type, rarely modified after initialization. */ interface CoreMemoryData { readonly agentId: string; readonly role: AgentRole; readonly name: string; readonly constraints: readonly string[]; readonly capabilities: readonly string[]; readonly systemPrompt?: string; readonly temperament?: 'cautious' | 'balanced' | 'exploratory'; } interface ICoreMemory { getIdentity(agentId: string): Promise>; setIdentity(data: CoreMemoryData): Promise>; getConstraints(agentId: string): Promise>; updateConstraints(agentId: string, constraints: readonly string[]): Promise>; } /** * Episodic memory stores task experiences and interaction history. * Used for learning from past interactions and avoiding repeated mistakes. */ interface EpisodeData { readonly episodeId: string; readonly taskId: string; readonly agentId: string; readonly action: string; readonly outcome: 'success' | 'failure' | 'partial'; readonly context: Record; readonly learnings?: readonly string[]; readonly timestamp: Date; readonly durationMs?: number; } interface IEpisodicMemory { recordEpisode(episode: EpisodeData): Promise>; getEpisodes(agentId: string, limit?: number): Promise>; getEpisodesByTask(taskId: string): Promise>; getRecentFailures(agentId: string, limit?: number): Promise>; searchEpisodes(query: string, limit?: number): Promise>; } /** * Semantic memory stores domain facts and learned information. * Used for general knowledge that applies across tasks. */ interface SemanticFact { readonly factId: string; readonly domain: string; readonly subject: string; readonly predicate: string; readonly object: string; readonly confidence: number; readonly source?: string; readonly validUntil?: Date; } interface ISemanticMemory { storeFact(fact: SemanticFact): Promise>; getFact(factId: string): Promise>; queryByDomain(domain: string, limit?: number): Promise>; queryBySubject(subject: string, limit?: number): Promise>; searchFacts(query: string, limit?: number): Promise>; invalidateFact(factId: string): Promise>; } /** * Procedural memory stores skills, workflows, and action patterns. * Used for learned procedures that can be reused across tasks. */ interface ProcedureStep { readonly stepId: string; readonly action: string; readonly parameters?: Record; readonly preconditions?: readonly string[]; readonly postconditions?: readonly string[]; } interface Procedure { readonly procedureId: string; readonly name: string; readonly description: string; readonly steps: readonly ProcedureStep[]; readonly triggerConditions: readonly string[]; readonly successRate: number; readonly executionCount: number; readonly averageDurationMs?: number; readonly tags?: readonly string[]; } interface IProceduralMemory { storeProcedure(procedure: Procedure): Promise>; getProcedure(procedureId: string): Promise>; findProcedures(triggerContext: string, limit?: number): Promise>; updateSuccessRate(procedureId: string, success: boolean): Promise>; searchProcedures(query: string, limit?: number): Promise>; } /** * Resource memory stores references to external data (files, URLs, APIs). * Used for tracking data sources and their freshness. */ interface ResourceReference { readonly resourceId: string; readonly type: 'file' | 'url' | 'api' | 'database' | 'other'; readonly location: string; readonly name: string; readonly mimeType?: string; readonly size?: number; readonly hash?: string; readonly lastAccessed: Date; readonly lastModified?: Date; readonly metadata?: Record; } interface IResourceMemory { storeResource(resource: ResourceReference): Promise>; getResource(resourceId: string): Promise>; findByType(type: ResourceReference['type'], limit?: number): Promise>; findByLocation(locationPattern: string): Promise>; updateLastAccessed(resourceId: string): Promise>; searchResources(query: string, limit?: number): Promise>; } /** * Knowledge vault stores persistent data that survives across sessions. * Used for long-term knowledge and critical information. */ interface VaultEntry { readonly vaultId: string; readonly category: 'insight' | 'decision' | 'pattern' | 'config' | 'archive'; readonly title: string; readonly content: unknown; readonly importance: 'critical' | 'high' | 'normal'; readonly createdAt: Date; readonly updatedAt: Date; readonly expiresAt?: Date; readonly tags?: readonly string[]; readonly relatedIds?: readonly string[]; } interface IKnowledgeVault { store(entry: VaultEntry): Promise>; retrieve(vaultId: string): Promise>; findByCategory(category: VaultEntry['category'], limit?: number): Promise>; findByImportance(importance: VaultEntry['importance'], limit?: number): Promise>; searchVault(query: string, limit?: number): Promise>; archive(vaultId: string): Promise>; getExpired(): Promise>; } /** * nexus-agents/context - Belief Core Types * * Core type definitions for belief states including confidence levels, * source types, and the fundamental Belief interface. * * @module context/belief-core-types * @see belief-types for re-exports * (Source: Issue #336, arXiv:2512.12818 - Hindsight Belief Memory) */ /** * Confidence level for belief states. * Based on evidence quality and reasoning chain length. */ declare const BeliefConfidence: { /** Strong evidence, short reasoning chain */ readonly HIGH: "high"; /** Moderate evidence or indirect inference */ readonly MEDIUM: "medium"; /** Weak evidence or long inference chain */ readonly LOW: "low"; /** Speculative or hypothetical */ readonly SPECULATIVE: "speculative"; }; type BeliefConfidence = (typeof BeliefConfidence)[keyof typeof BeliefConfidence]; /** * Source type for belief origin tracking. */ declare const BeliefSourceType: { /** Direct observation from environment */ readonly OBSERVATION: "observation"; /** Inference from other beliefs */ readonly INFERENCE: "inference"; /** External knowledge or provided fact */ readonly EXTERNAL: "external"; /** User-provided information */ readonly USER_INPUT: "user_input"; /** Hindsight correction from outcome */ readonly HINDSIGHT: "hindsight"; /** Default or prior belief */ readonly PRIOR: "prior"; }; type BeliefSourceType = (typeof BeliefSourceType)[keyof typeof BeliefSourceType]; /** * A belief represents an agent's held proposition about the world. * Beliefs are versioned and traceable to their sources. */ interface Belief { /** Unique identifier for this belief */ readonly beliefId: string; /** The entity this belief is about */ readonly subject: string; /** The property or relation being described */ readonly predicate: string; /** The value or target of the relation */ readonly object: string; /** Confidence level in this belief */ readonly confidence: BeliefConfidence; /** Source type for this belief */ readonly sourceType: BeliefSourceType; /** Reference to source evidence or reasoning */ readonly sourceRef?: string; /** Parent belief IDs if derived through inference */ readonly derivedFrom?: readonly string[]; /** Version number for tracking updates */ readonly version: number; /** When this belief was formed */ readonly createdAt: Date; /** When this belief was last updated */ readonly updatedAt: Date; /** Whether this belief has been superseded */ readonly superseded: boolean; /** ID of belief that superseded this one */ readonly supersededBy?: string; /** Domain or context for this belief */ readonly domain?: string; /** Additional metadata */ readonly metadata?: Record; } /** * nexus-agents/context - Belief Update Types * * Type definitions for belief update operations, queries, and audit records. * * @module context/belief-update-types * @see belief-types for re-exports * (Source: Issue #336, arXiv:2512.12818 - Hindsight Belief Memory) */ /** * Types of belief update operations. */ declare const BeliefUpdateType: { /** Add a new belief (retain) */ readonly RETAIN: "retain"; /** Update confidence or metadata */ readonly REVISE: "revise"; /** Mark belief as superseded */ readonly SUPERSEDE: "supersede"; /** Hindsight correction based on outcome */ readonly CORRECT: "correct"; /** Strengthen belief based on corroboration */ readonly REINFORCE: "reinforce"; /** Weaken belief based on contradicting evidence */ readonly WEAKEN: "weaken"; }; type BeliefUpdateType = (typeof BeliefUpdateType)[keyof typeof BeliefUpdateType]; /** * Record of a belief update for audit trail. */ interface BeliefUpdate { /** Unique identifier for this update */ readonly updateId: string; /** ID of the belief being updated */ readonly beliefId: string; /** Type of update operation */ readonly updateType: BeliefUpdateType; /** Previous state (for revisions) */ readonly previousState?: Partial; /** New state after update */ readonly newState: Partial; /** Reason for the update */ readonly reason: string; /** Evidence supporting this update */ readonly evidence?: string; /** When this update occurred */ readonly timestamp: Date; /** Agent or process that made the update */ readonly updatedBy?: string; } /** * Query options for retrieving beliefs. */ interface BeliefQuery { /** Filter by subject entity */ readonly subject?: string; /** Filter by predicate */ readonly predicate?: string; /** Filter by domain */ readonly domain?: string; /** Minimum confidence level */ readonly minConfidence?: BeliefConfidence; /** Include superseded beliefs */ readonly includeSuperseded?: boolean; /** Filter by source type */ readonly sourceType?: BeliefSourceType; /** Maximum number of results */ readonly limit?: number; /** Order by field */ readonly orderBy?: 'createdAt' | 'updatedAt' | 'confidence'; /** Order direction */ readonly orderDirection?: 'asc' | 'desc'; } /** * nexus-agents/context - Belief Hindsight Types * * Type definitions for counterfactual reasoning and hindsight learning. * * @module context/belief-hindsight-types * @see belief-types for re-exports * (Source: Issue #336, arXiv:2512.12818 - Hindsight Belief Memory) */ /** * A counterfactual represents an alternative scenario for reasoning. */ interface Counterfactual { /** Unique identifier */ readonly counterfactualId: string; /** The hypothetical change to consider */ readonly hypothesis: string; /** Beliefs that would change under this hypothesis */ readonly affectedBeliefs: readonly string[]; /** Predicted outcomes under this scenario */ readonly predictedOutcomes: readonly string[]; /** Actual outcomes if hypothesis was tested */ readonly actualOutcomes?: readonly string[]; /** Whether the counterfactual was validated */ readonly validated: boolean; /** When this counterfactual was created */ readonly createdAt: Date; /** Task or context that prompted this counterfactual */ readonly taskContext?: string; } /** * Hindsight record captures learning from outcomes. */ interface HindsightRecord { /** Unique identifier */ readonly hindsightId: string; /** Task that produced this hindsight */ readonly taskId: string; /** Beliefs held before the task */ readonly priorBeliefs: readonly string[]; /** Expected outcome based on prior beliefs */ readonly expectedOutcome: string; /** Actual outcome observed */ readonly actualOutcome: string; /** Whether expectation matched reality */ readonly outcomeMatched: boolean; /** Beliefs that were corrected */ readonly correctedBeliefs: readonly string[]; /** New beliefs formed from this experience */ readonly newBeliefs: readonly string[]; /** Lessons learned */ readonly lessons: readonly string[]; /** When this record was created */ readonly createdAt: Date; } /** * nexus-agents/context - Belief Memory Interface * * Interface definition for Hindsight Belief Memory operations, * statistics types, and configuration options. * * @module context/belief-memory-interface * @see belief-types for re-exports * (Source: Issue #336, arXiv:2512.12818 - Hindsight Belief Memory) */ /** * Interface for Hindsight Belief Memory operations. * Implements the three core operations: retain, recall, and reflect. */ interface IHindsightBeliefMemory { /** * Store a new belief. * @param belief - The belief to store (without beliefId, version, timestamps) */ retain(belief: Omit): Promise>; /** * Store multiple beliefs atomically. */ retainBatch(beliefs: readonly Omit[]): Promise>; /** * Retrieve a belief by ID. */ recall(beliefId: string): Promise>; /** * Query beliefs with filters. */ query(query: BeliefQuery): Promise>; /** * Get all beliefs about a subject. */ recallBySubject(subject: string, limit?: number): Promise>; /** * Get current belief for a subject-predicate pair. */ recallCurrent(subject: string, predicate: string): Promise>; /** * Get belief history for a subject-predicate pair. */ recallHistory(subject: string, predicate: string, limit?: number): Promise>; /** * Update a belief with a new version. */ revise(beliefId: string, updates: Partial>, reason: string): Promise>; /** * Supersede a belief with a new one. */ supersede(beliefId: string, newBelief: Omit, reason: string): Promise>; /** * Apply hindsight correction to beliefs. */ applyHindsight(record: HindsightRecord): Promise>; /** * Reinforce a belief based on corroborating evidence. */ reinforce(beliefId: string, evidence: string): Promise>; /** * Weaken a belief based on contradicting evidence. */ weaken(beliefId: string, evidence: string): Promise>; /** * Create a counterfactual scenario. */ createCounterfactual(hypothesis: string, taskContext?: string): Promise>; /** * Validate a counterfactual with actual outcomes. */ validateCounterfactual(counterfactualId: string, actualOutcomes: readonly string[]): Promise>; /** * Get counterfactuals for a task context. */ getCounterfactuals(taskContext: string): Promise>; /** * Get update history for a belief. */ getUpdateHistory(beliefId: string): Promise>; /** * Get hindsight records for a task. */ getHindsightRecords(taskId: string): Promise>; /** * Get belief memory statistics. */ getStats(): Promise>; /** * Prune old superseded beliefs. */ pruneSuperseded(olderThan: Date): Promise>; } /** * Statistics for belief memory. */ interface BeliefMemoryStats { readonly totalBeliefs: number; readonly activeBeliefs: number; readonly supersededBeliefs: number; readonly beliefsByConfidence: Record; readonly beliefsBySource: Record; readonly totalUpdates: number; readonly totalCounterfactuals: number; readonly totalHindsightRecords: number; readonly oldestBelief?: Date; readonly newestBelief?: Date; } /** * nexus-agents/context - Typed Memory Architecture * * Implements MIRIX-style typed memory system with six distinct memory types * for improved agent coordination and context management. * * @module context/memory-types * (Source: Issue #101, arXiv:2507.07957 - MIRIX Architecture) */ /** * Seven distinct memory types: six from MIRIX architecture plus Belief Memory. * (Source: arXiv:2507.07957 - MIRIX, arXiv:2512.12818 - Hindsight Belief Memory) */ declare const MemoryType: { readonly CORE: "core"; readonly EPISODIC: "episodic"; readonly SEMANTIC: "semantic"; readonly PROCEDURAL: "procedural"; readonly RESOURCE: "resource"; readonly VAULT: "vault"; /** Hindsight Belief Memory for reasoning agents (arXiv:2512.12818) */ readonly BELIEF: "belief"; }; type MemoryType = (typeof MemoryType)[keyof typeof MemoryType]; /** * Base typed memory entry with type discrimination. */ interface TypedMemoryEntry { readonly id: string; readonly type: T; readonly key: string; readonly value: unknown; readonly metadata: MemoryMetadata; readonly createdAt: Date; readonly accessedAt: Date; readonly agentId?: string; readonly relevanceScore?: number; } /** * Unified typed memory interface providing access to all seven memory types. * (Source: Issue #101, arXiv:2507.07957 - MIRIX, arXiv:2512.12818 - Hindsight) */ interface ITypedMemory { readonly core: ICoreMemory; readonly episodic: IEpisodicMemory; readonly semantic: ISemanticMemory; readonly procedural: IProceduralMemory; readonly resource: IResourceMemory; readonly vault: IKnowledgeVault; /** Hindsight Belief Memory for reasoning agents (arXiv:2512.12818) */ readonly belief: IHindsightBeliefMemory; /** Query entries by memory type */ queryByType(type: MemoryType, query: string, limit?: number): Promise>; /** Filter memories by relevance to an agent role */ filterByRelevance(agentRole: AgentRole, limit?: number): Promise>; /** Get memory statistics across all types */ getStats(): Promise>; /** Prune expired entries across all memory types */ pruneExpired(): Promise>; } /** * Statistics for typed memory usage. */ interface TypedMemoryStats { readonly totalEntries: number; readonly entriesByType: Record; /** Whether each count is complete, capped, or unavailable. */ readonly coverage: Record; /** Search cap when at least one count is truncated. */ readonly cap?: number; readonly oldestEntry?: Date; readonly newestEntry?: Date; readonly totalSizeBytes?: number; } /** * Result of pruning expired entries. */ interface TypedMemoryPruneResult { readonly prunedCount: number; readonly prunedByType: Record; readonly freedBytes?: number; } /** * Configuration for role-based memory filtering. */ interface RelevanceFilterConfig { /** Memory types relevant to each role */ readonly roleMemoryTypes: Record; /** Minimum relevance score to include (0-1) */ readonly minRelevanceScore: number; /** Maximum entries to return per type */ readonly maxEntriesPerType: number; } /** * nexus-agents/agents - Agent State Machine Types * * Type definitions and transition configuration for AgentStateMachine. * * (Source: Nexus Agents CLAUDE.md, Agent State Machine Design) */ /** * State transition event types. */ type StateTransitionEvent = 'task_assigned' | 'plan_completed' | 'needs_input' | 'task_completed' | 'failure' | 'input_received' | 'recovered'; /** * State transition metadata. */ interface StateTransition { /** Previous state */ from: AgentState$2; /** New state */ to: AgentState$2; /** Event that triggered the transition */ event: StateTransitionEvent; /** Timestamp of the transition */ timestamp: string; /** Optional context data */ context?: Record; } /** * Callback for state change events. */ type StateChangeCallback = (transition: StateTransition) => void; /** * Error callback for invalid transitions. */ type TransitionErrorCallback = (currentState: AgentState$2, attemptedEvent: StateTransitionEvent, error: AgentError$1) => void; /** * State machine options. */ interface StateMachineOptions { /** Initial state (defaults to 'idle') */ initialState?: AgentState$2; /** Maximum error count before permanent error state */ maxErrorCount?: number; /** Enable transition history tracking */ trackHistory?: boolean; /** Maximum history entries to keep */ maxHistorySize?: number; } /** * nexus-agents/agents - Agent State Machine * * Manages agent state transitions with validation, events, and error recovery. * * States: * - idle: Agent is ready for tasks * - thinking: Agent is analyzing/planning * - acting: Agent is performing work * - waiting: Agent is waiting for input/response * - error: Agent encountered an error * * (Source: Nexus Agents CLAUDE.md, Agent State Machine Design) */ /** * Agent State Machine. * * Manages agent lifecycle states with validation, event callbacks, * and error recovery mechanisms. */ declare class AgentStateMachine { private currentState; private readonly stateChangeCallbacks; private readonly errorCallbacks; private readonly history; private errorCount; private readonly maxErrorCount; private readonly trackHistory; private readonly maxHistorySize; constructor(options?: StateMachineOptions); /** * Gets the current state. */ get state(): AgentState$2; /** * Gets the transition history. */ get transitionHistory(): readonly StateTransition[]; /** * Gets the current error count. */ get errors(): number; /** * Checks if a transition is valid from the current state. */ canTransition(event: StateTransitionEvent): boolean; /** * Gets the next state for an event, if valid. */ getNextState(event: StateTransitionEvent): AgentState$2 | undefined; /** * Gets all valid events from the current state. */ getValidEvents(): StateTransitionEvent[]; /** * Attempts a state transition. * * @param event - The event triggering the transition * @param context - Optional context data for the transition * @returns Result with the new state or an AgentError */ transition(event: StateTransitionEvent, context?: Record): Result; /** * Forces a transition to the error state. * Use for unrecoverable errors that should bypass normal transition rules. * * @param context - Optional context data about the error */ forceError(context?: Record): void; /** * Attempts recovery from the error state. * * @param context - Optional context data about the recovery * @returns Result with the new state or an AgentError if recovery failed */ recover(context?: Record): Result; /** * Resets the error count. Call after successful task completion. */ resetErrorCount(): void; /** * Resets the state machine to its initial state. * * @param clearHistory - Whether to clear the transition history */ reset(clearHistory?: boolean): void; /** * Subscribes to state change events. * * @param callback - Callback to invoke on state changes * @returns Unsubscribe function */ onStateChange(callback: StateChangeCallback): () => void; /** * Subscribes to transition error events. * * @param callback - Callback to invoke on transition errors * @returns Unsubscribe function */ onTransitionError(callback: TransitionErrorCallback): () => void; /** * Checks if the agent is in a state where it can accept new tasks. */ isAvailable(): boolean; /** * Checks if the agent is currently working. */ isWorking(): boolean; /** * Checks if the agent is in an error state. */ hasError(): boolean; private createTransition; private applyTransition; private pruneHistory; private notifyStateChangeCallbacks; private notifyErrorCallbacks; } /** * Creates a new agent state machine. * * @param options - State machine options * @returns A new AgentStateMachine instance */ declare function createStateMachine(options?: StateMachineOptions): AgentStateMachine; /** * Event Bus Core Type Definitions * * Base types, interfaces, and infrastructure for the event bus. * * @module agents/collaboration/event-bus-core-types * (Source: Issue #182, ARCHITECTURE.md Hybrid Architecture) */ /** * Unique identifier for event subscriptions. */ type SubscriptionId = string; /** * Event topic patterns support wildcards: * - 'session.created' - exact match * - 'session.*' - matches session.created, session.completed, etc. * - '*' - matches all events */ type TopicPattern = string; /** * Base event structure for all domain events. */ interface DomainEvent { /** Unique event identifier */ readonly eventId: string; /** ISO 8601 timestamp */ readonly timestamp: string; /** Event topic for routing */ readonly topic: string; /** Optional correlation ID for tracing */ readonly correlationId?: string; /** Optional session ID for scoping */ readonly sessionId?: string; /** Event payload (type-specific) */ readonly payload: unknown; } /** * Event listener function type. */ type EventListener = (event: T) => void | Promise; /** * Subscription handle for managing event subscriptions. */ interface Subscription { /** Unique subscription identifier */ readonly id: SubscriptionId; /** Topic pattern this subscription matches */ readonly pattern: TopicPattern; /** Unsubscribe from events */ unsubscribe(): void; } /** * Event filter for querying event history. */ interface EventFilter$1 { /** Filter by topic pattern */ topic?: TopicPattern; /** Filter by session ID */ sessionId?: string; /** Filter by correlation ID */ correlationId?: string; /** Filter events after this timestamp */ after?: string; /** Filter events before this timestamp */ before?: string; /** Maximum number of events to return */ limit?: number; } /** * Event bus statistics. */ interface EventBusStats { /** Total events emitted */ eventsEmitted: number; /** Total subscriptions created */ subscriptionsCreated: number; /** Currently active subscriptions */ activeSubscriptions: number; /** Events in history */ historySize: number; /** Errors encountered */ errorCount: number; } /** * Event bus interface for agent-to-agent communication. */ interface ICollaborationEventBus { /** * Emit an event to all matching subscribers. * @param event - The event to emit */ emit(event: DomainEvent): void; /** * Emit an event and wait for all handlers to complete. * @param event - The event to emit */ emitAsync(event: DomainEvent): Promise; /** * Subscribe to events matching a topic pattern. * @param pattern - Topic pattern (supports wildcards) * @param listener - Event handler function * @returns Subscription handle */ subscribe(pattern: TopicPattern, listener: EventListener): Subscription; /** * Unsubscribe from events. * @param subscriptionId - Subscription ID to remove */ unsubscribe(subscriptionId: SubscriptionId): void; /** * Get event history matching filter criteria. * @param filter - Optional filter criteria * @returns Array of matching events */ getHistory(filter?: EventFilter$1): readonly DomainEvent[]; /** * Clear event history. */ clearHistory(): void; /** * Get event bus statistics. */ getStats(): EventBusStats; /** * Check if a topic pattern has any subscribers. * @param pattern - Topic pattern to check */ hasSubscribers(pattern: TopicPattern): boolean; } /** * nexus-agents/agents - Collaboration Schemas * * Zod schemas for collaboration protocol validation. */ /** * Zod schema for CollaborationPattern. */ declare const CollaborationPatternSchema: z.ZodEnum<{ review: "review"; consensus: "consensus"; sequential: "sequential"; parallel: "parallel"; reflexion: "reflexion"; aegean: "aegean"; "self-refine": "self-refine"; "self-debug": "self-debug"; }>; /** * Zod schema for SessionStatus. */ declare const SessionStatusSchema: z.ZodEnum<{ failed: "failed"; completed: "completed"; pending: "pending"; in_progress: "in_progress"; awaiting_review: "awaiting_review"; voting: "voting"; finalizing: "finalizing"; timed_out: "timed_out"; }>; /** * Zod schema for VoteDecision. */ declare const VoteDecisionSchema: z.ZodEnum<{ approve: "approve"; reject: "reject"; abstain: "abstain"; }>; /** * Zod schema for CollaborationConfig. */ declare const CollaborationConfigSchema: z.ZodObject<{ sessionId: z.ZodString; pattern: z.ZodEnum<{ review: "review"; consensus: "consensus"; sequential: "sequential"; parallel: "parallel"; reflexion: "reflexion"; aegean: "aegean"; "self-refine": "self-refine"; "self-debug": "self-debug"; }>; experts: z.ZodArray; task: z.ZodObject<{ id: z.ZodString; description: z.ZodString; context: z.ZodRecord; constraints: z.ZodOptional; maxTokens: z.ZodOptional; outputFormat: z.ZodOptional>; allowedTools: z.ZodOptional>; }, z.core.$strip>>; priority: z.ZodOptional; }, z.core.$strip>; timeout: z.ZodOptional; minVotes: z.ZodOptional; requireUnanimous: z.ZodOptional; maxRetries: z.ZodOptional; }, z.core.$strip>; /** * Zod schema for ExpertParticipation. */ declare const ExpertParticipationSchema: z.ZodObject<{ expertId: z.ZodString; role: z.ZodEnum<{ custom: "custom"; orchestrator: "orchestrator"; code_expert: "code_expert"; architecture_expert: "architecture_expert"; security_expert: "security_expert"; documentation_expert: "documentation_expert"; testing_expert: "testing_expert"; }>; joinedAt: z.ZodISODateTime; status: z.ZodEnum<{ failed: "failed"; working: "working"; pending: "pending"; submitted: "submitted"; reviewing: "reviewing"; voted: "voted"; }>; submittedAt: z.ZodOptional; retryCount: z.ZodNumber; }, z.core.$strip>; /** * Zod schema for VoteMessage. */ declare const VoteMessageSchema: z.ZodObject<{ type: z.ZodLiteral<"vote">; expertId: z.ZodString; decision: z.ZodEnum<{ approve: "approve"; reject: "reject"; abstain: "abstain"; }>; reasoning: z.ZodString; conditions: z.ZodOptional>; }, z.core.$strip>; /** * Zod schema for ReviewResponseMessage. */ declare const ReviewResponseMessageSchema: z.ZodObject<{ type: z.ZodLiteral<"review_response">; reviewerId: z.ZodString; requesterId: z.ZodString; approved: z.ZodBoolean; feedback: z.ZodString; suggestions: z.ZodOptional>; severity: z.ZodOptional>; }, z.core.$strip>; /** * Default collaboration timeouts. */ declare const DEFAULT_TIMEOUTS: { readonly sequential: number; readonly parallel: number; readonly review: number; readonly consensus: number; readonly reflexion: number; readonly aegean: number; readonly 'self-refine': number; readonly 'self-debug': number; }; /** * Default retry counts. */ declare const DEFAULT_MAX_RETRIES = 2; /** * Minimum number of experts for each pattern. */ declare const MIN_EXPERTS_FOR_PATTERN: { readonly sequential: 1; readonly parallel: 2; readonly review: 2; readonly consensus: 3; readonly reflexion: 1; readonly aegean: 3; readonly 'self-refine': 1; readonly 'self-debug': 1; }; /** * nexus-agents/agents - Collaboration Types * * Type definitions for expert collaboration protocol. * Defines patterns for sequential, parallel, review, and consensus collaboration. */ /** * Collaboration pattern types. * - sequential: Experts work in order, passing results forward * - parallel: Experts work simultaneously on the same task * - review: One expert reviews another's work * - consensus: Voting-based decision making * - reflexion: Multi-agent reflexion with persona-based critics (arxiv:2512.20845) * - aegean: Byzantine-fault-tolerant consensus (arxiv:2512.20184) * - self-refine: Iterative refinement with self-feedback (arxiv:2303.17651) * - self-debug: Automatic error detection and repair (arxiv:2304.05128) */ type CollaborationPattern = 'sequential' | 'parallel' | 'review' | 'consensus' | 'reflexion' | 'aegean' | 'self-refine' | 'self-debug'; /** * Session status during collaboration lifecycle. */ type SessionStatus = 'pending' | 'in_progress' | 'awaiting_review' | 'voting' | 'finalizing' | 'completed' | 'failed' | 'timed_out'; /** * Vote decision options for consensus protocol. */ type VoteDecision = 'approve' | 'reject' | 'abstain'; /** * Configuration for a collaboration session. */ interface CollaborationConfig { sessionId: string; pattern: CollaborationPattern; experts: string[]; task: Task$1; timeout?: number; minVotes?: number; requireUnanimous?: boolean; maxRetries?: number; } /** * Expert participation record in a session. */ interface ExpertParticipation { expertId: string; role: AgentRole; joinedAt: string; status: 'pending' | 'working' | 'submitted' | 'reviewing' | 'voted' | 'failed'; submittedAt?: string; retryCount: number; } /** * Collaboration message types for inter-expert communication. */ type CollaborationMessage = TaskAssignmentMessage | ResultSubmissionMessage | ReviewRequestMessage | ReviewResponseMessage | FeedbackMessage | VoteMessage | StatusUpdateMessage; /** * Task assignment message sent to an expert. */ interface TaskAssignmentMessage { type: 'task_assignment'; expertId: string; task: Task$1; sequencePosition?: number; previousResults?: TaskResult[]; deadline?: string; } /** * Result submission from an expert. */ interface ResultSubmissionMessage { type: 'result_submission'; expertId: string; result: TaskResult; confidence?: number; notes?: string; } /** * Review request from one expert to another. */ interface ReviewRequestMessage { type: 'review_request'; fromExpert: string; toExpert: string; artifact: unknown; criteria?: string[]; deadline?: string; } /** * Review response from a reviewer. */ interface ReviewResponseMessage { type: 'review_response'; reviewerId: string; requesterId: string; approved: boolean; feedback: string; suggestions?: string[]; severity?: 'none' | 'minor' | 'major' | 'critical'; } /** * General feedback message. */ interface FeedbackMessage { type: 'feedback'; expertId: string; targetExpertId?: string; feedback: string; category?: 'improvement' | 'concern' | 'praise' | 'question'; } /** * Vote message for consensus protocol. */ interface VoteMessage { type: 'vote'; expertId: string; decision: VoteDecision; reasoning: string; conditions?: string[]; } /** * Status update message. */ interface StatusUpdateMessage { type: 'status_update'; expertId: string; status: ExpertParticipation['status']; progress?: number; estimatedTimeRemaining?: number; } /** * Aggregated session status. */ interface SessionState { config: CollaborationConfig; status: SessionStatus; participants: ExpertParticipation[]; results: Map; reviews: ReviewResponseMessage[]; votes: VoteMessage[]; startedAt: string; completedAt?: string; error?: string; messageLog: CollaborationMessage[]; } /** * Final collaboration result. */ interface CollaborationResult { sessionId: string; pattern: CollaborationPattern; aggregatedResult: AggregatedResult; expertResults: ExpertResultSummary[]; durationMs: number; success: boolean; error?: string; } /** * Summary of an expert's contribution. */ interface ExpertResultSummary { expertId: string; role: AgentRole; result?: TaskResult; contributionScore: number; executionTimeMs: number; success: boolean; error?: string; } /** * Aggregated result from multiple experts. */ interface AggregatedResult { output: unknown; strategy: 'merge' | 'select_best' | 'consensus' | 'sequential_chain'; qualityScore: number; conflicts: ResultConflict[]; metadata: AggregationMetadata; } /** * Conflict between expert results. */ interface ResultConflict { expert1Id: string; expert2Id: string; field: string; description: string; resolution: 'expert1' | 'expert2' | 'merged' | 'unresolved'; resolutionReason?: string; } /** * Metadata about the aggregation process. */ interface AggregationMetadata { resultCount: number; conflictCount: number; averageConfidence: number; totalTokensUsed: number; /** * How many contributors reported no measured usage (#4743). * * `totalTokensUsed` sums what was measured. A contributor whose adapter * reported nothing carries a placeholder `0` (`ResultMetadata.tokensMeasured * === false`), so without this count the total reads as complete when it is a * LOWER BOUND. Absent means the aggregate predates the distinction — unknown, * not zero. */ unmeasuredResults?: number; /** * Whether `averageConfidence` is a measurement (#4831). * * `false` means no contributor carried a confidence signal, so * `averageConfidence` is a placeholder `0` and NOT a score — a session whose * confidence was never assessed must not read as a confident one. The * collaboration-session builder is in that position: `TaskResult` has no * confidence field, while the `ResultAggregator` path computes the value * from `ExpertResult.confidence`. * * Absent means the producer predates the distinction — unknown, not * measured. Mirrors `ResultMetadata.tokensMeasured` (#4734). */ confidenceMeasured?: boolean; /** * Whether `conflicts` is the outcome of a comparison (#4854). * * `false` means nothing was compared, so an empty `conflicts` list and a * `conflictCount` of 0 are the absence of a check — not the absence of * disagreement. They are byte-identical to what a genuinely unanimous * session produces, which is exactly why the distinction has to be stated * rather than inferred. The collaboration-session builder is in that * position; the `ResultAggregator` path compares fields pairwise. * * Absent means the producer predates the distinction — unknown, not * checked. Mirrors `confidenceMeasured` (#4831). */ conflictsDetected?: boolean; aggregatedAt: string; } /** * Base interface for collaboration protocols. * * NOTE: This interface is defined here (not in collaboration-protocol.ts) to avoid * circular dependencies. Protocol implementations import this interface, and * collaboration-protocol.ts imports the implementations. */ interface ICollaborationProtocol { readonly pattern: CollaborationConfig['pattern']; execute(config: CollaborationConfig, agents: Map): Promise>; cancel(reason: string): void; } /** * Options for protocol execution. * * NOTE: sessionOptions uses a generic Record type to avoid circular dependency * with collaboration-session.ts. The actual type is CollaborationSessionOptions * which is defined in collaboration-session.ts. */ interface ProtocolOptions { logger?: ILogger; /** Session options - accepts CollaborationSessionOptions from collaboration-session.ts */ sessionOptions?: Record; sequentialDelay?: number; continueOnFailure?: boolean; } /** * Priority levels for context content. * Higher priority content is retained longer during pruning. */ declare const ContentPriority: { /** System instructions - highest priority, never pruned */ readonly SYSTEM: 100; /** Current task description and requirements */ readonly TASK: 80; /** Active working content (recent code, research) */ readonly ACTIVE: 60; /** Historical context (older messages, results) */ readonly HISTORY: 40; /** Ephemeral content (debug logs, temp data) */ readonly EPHEMERAL: 20; }; type ContentPriority = (typeof ContentPriority)[keyof typeof ContentPriority]; /** * Budget allocation for context categories. * Based on PROJECT_PLAN.md recommendations. */ interface ContextBudget { /** System instructions and project context (default: 15%) */ system: number; /** Current task description and requirements (default: 20%) */ task: number; /** Active working content (default: 50%) */ active: number; /** Reserved for response generation (default: 15%) */ reserved: number; } /** * Default budget allocation percentages. */ declare const DEFAULT_BUDGET: ContextBudget; /** * Zod schema for ContextBudget validation. */ declare const ContextBudgetSchema: z.ZodObject<{ system: z.ZodNumber; task: z.ZodNumber; active: z.ZodNumber; reserved: z.ZodNumber; }, z.core.$strip>; /** * A piece of content in the context with its metadata. */ interface ContextItem { /** Unique identifier for this item */ id: string; /** The content (message, text, etc.) */ content: string; /** Priority level for retention */ priority: ContentPriority; /** Budget category this item belongs to */ category: ContextItemCategory; /** Token count for this item */ tokenCount: number; /** When this item was added */ addedAt: number; /** Optional metadata */ metadata?: Record; } /** * Type alias for context item categories (excludes 'reserved'). */ type ContextItemCategory = keyof Omit; /** * Configuration for ContextManager. */ interface ContextManagerConfig { /** Maximum context window size in tokens */ maxTokens: number; /** Budget allocation (defaults to DEFAULT_BUDGET) */ budget?: ContextBudget; /** Model adapter for token counting */ adapter?: IModelAdapter; /** Custom logger */ logger?: ILogger; /** Warning threshold (0-1) - warn when this % of budget is used */ warningThreshold?: number; } /** * Schema for ContextManagerConfig validation. */ declare const ContextManagerConfigSchema: z.ZodObject<{ maxTokens: z.ZodNumber; budget: z.ZodOptional>; warningThreshold: z.ZodOptional; }, z.core.$strip>; /** * Statistics about context usage. */ interface ContextStats { /** Total tokens currently used */ totalTokens: number; /** Tokens used per category */ categoryTokens: Record; /** Number of items per category */ itemCounts: Record; /** Available tokens (total - reserved) */ availableTokens: number; /** Whether any category is over budget */ isOverBudget: boolean; /** Categories that are over budget */ overBudgetCategories: ContextItemCategory[]; /** Percentage of total capacity used */ usagePercentage: number; } /** * nexus-agents/agents - ContextManager * * Manages context window for agents, enforcing token budgets * and content priority levels. Integrates with model adapters * for accurate token counting. */ /** * Manages context window for agents with token budget enforcement. */ declare class ContextManager { private readonly maxTokens; private readonly budget; private readonly adapter; private readonly logger; private readonly warningThreshold; private readonly items; private cachedStats; /** Running totals for token counts by category. O(1) lookups. */ private categoryTokenCounts; /** Running total token count across all categories. O(1) lookups. */ private totalTokenCount; constructor(config: ContextManagerConfig); /** Add an item to the context. Returns Result with the added item or error. */ add(item: Omit): Promise>; /** Validate that adding tokens would not exceed budget constraints. */ private validateBudgetConstraints; /** Check if adding tokens would exceed category budget. */ private checkCategoryBudget; /** Check if adding tokens would exceed total budget. */ private checkTotalBudget; /** Store an item, update running token count totals, and log the operation. */ private storeItem; /** Remove an item from the context. Returns true if removed, false if not found. */ remove(id: string): boolean; /** Get an item by ID. */ get(id: string): ContextItem | undefined; /** Check if an item with the given content can be added to a category. */ canAdd(content: string, category: ContextItemCategory): Promise; /** Get all items in a category, sorted by priority (desc) then addedAt (asc). */ getByCategory(category: ContextItemCategory): ContextItem[]; /** Get all items sorted by priority (desc) then addedAt (asc). */ getAllItems(): ContextItem[]; /** Build messages array from context items for model requests. */ buildMessages(): Message[]; /** Get the system prompt from system category items. */ getSystemPrompt(): string | undefined; /** Get current context statistics. */ getStats(): ContextStats; /** Get remaining tokens available in a category. */ getRemainingTokens(category: ContextItemCategory): number; /** Get total remaining tokens across all categories. */ getTotalRemainingTokens(): number; /** Clear all items from the context. */ clear(): void; /** Clear items from a specific category. Returns number of items removed. */ clearCategory(category: ContextItemCategory): number; /** Count tokens in text using adapter or fallback estimation. */ countTokens(text: string): Promise; /** Get the token budget for a category. */ private getCategoryBudget; /** Get current token count for a category. O(1). */ private getCategoryTokenCount; /** Get total token count across all categories. O(1). */ private getTotalTokenCount; /** Invalidate cached statistics. */ private invalidateCache; /** Add token count to running totals for a category. */ private addToTotals; /** Subtract token count from running totals for a category. */ private subtractFromTotals; /** Reset all token count totals to zero. */ private resetTokenCounts; /** Check if usage exceeds warning threshold and log. */ private checkWarningThreshold; } /** * Pruning Strategies Types and Constants * * Type definitions and constants for context pruning strategies. * * @module agents/pruning-strategies-types */ /** * Configuration options specific to sliding window strategy. */ interface SlidingWindowOptions { /** Number of recent messages to preserve (default: 10) */ preserveRecentCount: number; /** Whether to summarize older messages (default: true) */ summarizeOlder: boolean; } /** * Configuration options specific to hierarchical strategy. */ interface HierarchicalOptions { /** Always preserve system prompt (default: true) */ preserveSystemPrompt: boolean; /** Number of recent messages to preserve (default: 5) */ preserveRecentCount: number; /** Summarize middle section (default: true) */ summarizeMiddle: boolean; } /** * Configuration options specific to semantic strategy. */ interface SemanticOptions { /** Current task description for relevance scoring */ currentTask: string | undefined; /** Minimum relevance score to keep (0-1, default: 0.3) */ minRelevanceScore: number; /** Number of top relevant items to preserve (default: 10) */ topRelevantCount: number; } /** * Result of a pruning operation. */ interface PruneResult { removedItems: ContextItem[]; summarizedItems: ContextItem[]; summaryItem?: ContextItem; tokensFreed: number; targetReached: boolean; } /** Context pruning with priority-based retention and multiple strategies. */ /** Strategy for pruning context when budget is exceeded. */ declare const PruningStrategy: { readonly OLDEST_FIRST: "oldest_first"; readonly LOWEST_PRIORITY: "lowest_priority"; readonly PRIORITY_WEIGHTED_AGE: "priority_weighted_age"; readonly SUMMARIZE: "summarize"; readonly SLIDING_WINDOW: "sliding_window"; readonly HIERARCHICAL: "hierarchical"; readonly SEMANTIC: "semantic"; }; type PruningStrategy = (typeof PruningStrategy)[keyof typeof PruningStrategy]; /** Configuration for ContextPruner. */ interface ContextPrunerConfig { contextManager: ContextManager; adapter?: IModelAdapter; logger?: ILogger; defaultStrategy?: PruningStrategy; minItemsPerCategory?: number; protectedPriority?: ContentPriority; autoTriggerThreshold?: number; } declare const ContextPrunerConfigSchema: z.ZodObject<{ defaultStrategy: z.ZodOptional>; minItemsPerCategory: z.ZodOptional; protectedPriority: z.ZodOptional; autoTriggerThreshold: z.ZodOptional; }, z.core.$strip>; /** Options for a pruning operation. */ interface PruneOptions { targetTokens?: number; strategy?: PruningStrategy; categories?: Array>; summarizationPrompt?: string; slidingWindowOptions?: Partial; hierarchicalOptions?: Partial; semanticOptions?: Partial; } /** Handles context pruning with multiple strategies. */ declare class ContextPruner { private readonly contextManager; private readonly adapter; private readonly logger; private readonly defaultStrategy; private readonly minItemsPerCategory; private readonly protectedPriority; private readonly autoTriggerThreshold; constructor(config: ContextPrunerConfig); /** Check if pruning should be triggered based on usage threshold. */ shouldPrune(): boolean; /** Prune context to free tokens or reach target capacity. */ prune(options?: PruneOptions): Promise>; /** Execute the selected pruning strategy. */ private executeStrategy; /** Prune items from a specific category. */ pruneCategory(category: keyof Omit, targetTokens: number): Promise>; /** Get candidates for pruning from specified categories. */ getPruneCandidates(categories: Array>): ContextItem[]; /** Estimate tokens that can be freed from specified categories. */ estimateFreeableTokens(categories: Array>): number; private pruneOldestFirst; private pruneLowestPriority; private prunePriorityWeightedAge; private pruneWithSummarization; private pruneSlidingWindow; private pruneHierarchical; private pruneSemantic; /** Internal method that delegates to the helper function. */ private removeItemsToTargetInternal; } /** * nexus-agents/agents - BaseAgent Context Pruning Initialization (Issue #306) * * Helper module for initializing context pruning infrastructure in BaseAgent. * Extracted to reduce constructor complexity and file size in base-agent.ts. */ /** Configuration for automatic context pruning in BaseAgent (Issue #306, #479). */ interface ContextPrunerAgentConfig { /** Whether to enable automatic context pruning. Default: true (Issue #479). */ enabled?: boolean; /** Pruning strategy to use. Default: 'priority_weighted_age'. */ strategy?: PruningStrategy; /** Maximum tokens before pruning is triggered. Default: 100000 (100K). */ maxTokens?: number; /** Tokens reserved for response generation. Default: 10000 (10K). */ reserveTokens?: number; /** Usage threshold (0-1) at which pruning is triggered. Default: 0.9 (90%). */ triggerThreshold?: number; } /** Metrics for context pruning operations (Issue #306). */ interface ContextPruningMetrics { /** Total number of pruning rounds executed. */ pruningRounds: number; /** Total tokens pruned across all rounds. */ totalTokensPruned: number; /** Tokens pruned in the last pruning operation. */ lastPruningTokens: number; /** Items removed in the last pruning operation. */ lastPruningItemsRemoved: number; /** Whether the last pruning reached its target. */ lastPruningTargetReached: boolean; } /** * nexus-agents/agents - Memory Configuration Types * * Configuration types and constants for agent memory integration. * Extracted from base-agent-memory-init.ts for file size compliance. * * @module agents/memory-config-types */ /** * Memory persistence mode for automatic state saving. */ declare const MemoryPersistenceMode: { /** No automatic persistence */ readonly NONE: "none"; /** Persist on task completion */ readonly ON_TASK_COMPLETE: "on_task_complete"; /** Persist on explicit flush calls only */ readonly MANUAL: "manual"; }; type MemoryPersistenceMode = (typeof MemoryPersistenceMode)[keyof typeof MemoryPersistenceMode]; /** * Configuration for memory integration in BaseAgent (Issue #348). */ interface AgentMemoryConfig { /** Whether memory integration is enabled. Default: false (opt-in). */ enabled?: boolean; /** Memory backend for general storage. */ backend?: IContextMemoryBackend; /** Typed memory for MIRIX-style 6-type architecture. */ typedMemory?: ITypedMemory; /** Relevance filter configuration for role-based retrieval. */ relevanceConfig?: RelevanceFilterConfig; /** Automatic persistence mode. Default: 'on_task_complete'. */ persistenceMode?: MemoryPersistenceMode; /** Maximum entries to load on agent initialization. Default: 50. */ maxInitialLoadEntries?: number; /** Whether to automatically load relevant memories on init. Default: true. */ autoLoadOnInit?: boolean; } /** * nexus-agents/agents - Memory State Types * * Types for agent memory state, learnings, patterns, and error resolutions. * Extracted from base-agent-memory-init.ts for file size compliance. * * @module agents/memory-state-types */ /** * Serializable agent memory state for persistence. */ interface AgentMemoryState { /** Agent ID that owns this state */ agentId: string; /** Agent role for relevance filtering */ role: AgentRole; /** Timestamp of last persistence */ persistedAt: Date; /** Task learnings to persist */ taskLearnings: TaskLearning[]; /** Execution patterns observed */ executionPatterns: ExecutionPattern[]; /** Error resolutions for future reference */ errorResolutions: ErrorResolution[]; } /** * A learning captured from task execution. */ interface TaskLearning { /** Unique identifier */ id: string; /** Task type or category */ taskType: string; /** What was learned */ insight: string; /** Confidence score (0-1) */ confidence: number; /** When this was learned */ learnedAt: Date; /** Context in which it was learned */ context?: string; } /** * An observed execution pattern. */ interface ExecutionPattern { /** Pattern identifier */ id: string; /** Pattern description */ pattern: string; /** Number of times observed */ occurrences: number; /** Last observed timestamp */ lastSeen: Date; } /** * Resolution for a previously encountered error. */ interface ErrorResolution { /** Error signature or pattern */ errorPattern: string; /** How it was resolved */ resolution: string; /** Whether the resolution was successful */ successful: boolean; /** When this resolution was recorded */ resolvedAt: Date; } /** * Memory operation error. */ declare class AgentMemoryError extends Error { readonly context?: Record | undefined; constructor(message: string, context?: Record | undefined); } /** * nexus-agents/agents - BaseAgent Type Definitions * * Type definitions for BaseAgent, extracted to reduce file size in base-agent.ts. */ /** * Options for creating a BaseAgent. */ interface BaseAgentOptions { /** Unique agent identifier */ id: string; /** Agent role */ role: AgentRole; /** Agent capabilities */ capabilities: readonly AgentCapability[]; /** Model adapter for LLM interactions */ adapter?: IModelAdapter; /** Custom logger instance */ logger?: ILogger; /** System prompt for the agent */ systemPrompt?: string; /** Default temperature for completions */ temperature?: number; /** Maximum tokens for responses */ maxTokens?: number; /** Event bus for message observability (uses global bus if not provided) */ eventBus?: ICollaborationEventBus; /** Whether to emit events for message handling (default: true) */ emitMessageEvents?: boolean; /** State machine options for validated state transitions */ stateMachineOptions?: StateMachineOptions; /** Token budget configuration for EMA-based tracking (Issue #304) */ tokenBudget?: TokenBudgetConfig; /** Configuration for automatic context pruning (Issue #306) */ contextPruning?: ContextPrunerAgentConfig; /** Configuration for memory backend integration (Issue #348) */ memory?: AgentMemoryConfig; } /** * nexus-agents/agents - Agent Validation Schemas * * Zod schemas for validating agent-related data structures. */ /** * Zod schema for validating Task objects. */ declare const TaskSchema: z.ZodObject<{ id: z.ZodString; description: z.ZodString; context: z.ZodObject<{ workingDirectory: z.ZodOptional; files: z.ZodOptional>; history: z.ZodOptional; content: z.ZodString; timestamp: z.ZodString; }, z.core.$strip>>>; metadata: z.ZodOptional>; }, z.core.$strip>; constraints: z.ZodOptional; maxTokens: z.ZodOptional; }, z.core.$strip>>; priority: z.ZodOptional; }, z.core.$strip>; /** * Zod schema for validating AgentMessage objects. */ declare const AgentMessageSchema: z.ZodObject<{ id: z.ZodString; from: z.ZodString; to: z.ZodString; type: z.ZodEnum<{ status: "status"; result: "result"; task: "task"; query: "query"; feedback: "feedback"; }>; payload: z.ZodUnknown; timestamp: z.ZodString; }, z.core.$strip>; /** * Zod schema for validating BaseAgentOptions. */ declare const BaseAgentOptionsSchema: z.ZodObject<{ id: z.ZodString; role: z.ZodEnum<{ custom: "custom"; orchestrator: "orchestrator"; code_expert: "code_expert"; architecture_expert: "architecture_expert"; security_expert: "security_expert"; documentation_expert: "documentation_expert"; testing_expert: "testing_expert"; devops_expert: "devops_expert"; research_expert: "research_expert"; pm_expert: "pm_expert"; ux_expert: "ux_expert"; infrastructure_expert: "infrastructure_expert"; qa_expert: "qa_expert"; data_visualization_expert: "data_visualization_expert"; thinker: "thinker"; worker: "worker"; verifier: "verifier"; }>; capabilities: z.ZodArray>; systemPrompt: z.ZodOptional; temperature: z.ZodOptional; maxTokens: z.ZodOptional; contextPruning: z.ZodOptional; strategy: z.ZodOptional>; maxTokens: z.ZodOptional; reserveTokens: z.ZodOptional; triggerThreshold: z.ZodOptional; }, z.core.$strip>>; }, z.core.$strip>; /** * Abstract base class implementing IAgent with state management, logging, and model integration. * Memory backend integration (Issue #348) is implemented here with lifecycle methods. * * @module agents/base-agent */ /** Abstract base class for all agents. Subclasses must implement executeTask and buildPrompt. */ declare abstract class BaseAgent implements IAgent { readonly id: string; readonly role: AgentRole; readonly capabilities: readonly AgentCapability[]; protected readonly stateMachine: AgentStateMachine; protected readonly budgetTracker: ITokenBudgetTracker; protected adapter: IModelAdapter | undefined; protected readonly logger: ILogger; protected config: AgentConfig | undefined; protected sharedState: Record; protected history: Message[]; protected readonly systemPrompt: string | undefined; protected readonly temperature: number; protected readonly maxTokens: number; protected readonly eventBus: ICollaborationEventBus; protected readonly emitMessageEvents: boolean; private initialized; private readonly contextPruningEnabled; private readonly contextManager; private readonly contextPruner; private readonly pruningConfig; private pruningMetrics; private readonly memoryEnabled; private readonly memoryBackend; private readonly typedMemory; private readonly memoryConfig; private memoryState; private relevantMemories; /** * AbortSignal set by `execute()` when the caller passes one. `complete()` * forwards it onto `CompletionRequest.signal` so the in-flight model call * cancels when the caller's deadline wins a race (#3016/#3040). Set only * for the duration of one execute() and cleared in finally — the field is * single-task scoped and never crosses tasks. */ private currentExecutionSignal; constructor(options: BaseAgentOptions); get state(): AgentState$2; /** Builds the context state object for helper functions. */ private get contextState(); initialize(ctx: AgentContext): Promise>; execute(task: Task$1, options?: { signal?: AbortSignal; }): Promise>; handleMessage(msg: AgentMessage): Promise>; cleanup(): Promise; hasCapability(capability: AgentCapability): boolean; protected abstract executeTask(task: Task$1): Promise>; protected abstract buildPrompt(task: Task$1): Message[]; protected transformError(error: unknown, taskId: string): AgentError$1; protected complete(request: CompletionRequest): Promise>; protected addToHistory(message: Message): void; protected getHistory(): Message[]; protected clearHistory(): void; getPruningMetrics(): Readonly; protected addContextItem(content: string, priority?: (typeof ContentPriority)[keyof typeof ContentPriority], category?: 'system' | 'task' | 'active'): Promise; isContextPruningEnabled(): boolean; isMemoryEnabled(): boolean; getMemoryState(): Readonly | null; getRelevantMemories(): readonly TypedMemoryEntry[]; flushMemory(): Promise>; private get memOpCtx(); protected recordLearning(learning: Omit): void; protected recordPattern(p: Omit): void; protected recordResolution(r: Omit): void; protected findResolutionForError(errorMessage: string): ErrorResolution | undefined; protected getTaskLearnings(taskType: string): readonly TaskLearning[]; } /** * nexus-agents/agents - SimpleAgent * * A simple concrete agent implementation for testing and basic use cases. */ /** * Simple concrete agent implementation for testing and basic use cases. * * This agent processes tasks by sending them directly to the model adapter * and returning the response. */ declare class SimpleAgent extends BaseAgent { /** * Execute a task by sending it to the model. */ protected executeTask(task: Task$1): Promise>; /** Retry once on empty response — returns success if retry has content, error otherwise. */ private retryOnEmpty; /** * Build prompt messages from a task. */ protected buildPrompt(task: Task$1): Message[]; } /** * nexus-agents/agents - ICTM Types * * Core type definitions for the AOrchestra ICTM pattern. * ICTM = (Instructions, Context, Tools, Model) tuple for dynamic sub-agent creation. * * @see https://arxiv.org/abs/2602.03786 * @see Issue #756 * * @module agents/ictm/ictm-types */ /** * Context pruning strategy for sub-agent context curation. */ type ContextPruneStrategy = 'recency' | 'importance' | 'hybrid'; /** * Context filter configuration. * Controls what information flows to a sub-agent to prevent * long-horizon degradation (AOrchestra Section 3.2). */ interface ContextFilter { /** Maximum token budget for curated context */ maxTokens: number; /** Minimum relevance score (0-1) to include context items */ relevanceThreshold: number; /** Whether to include conversation history */ includeHistory: boolean; /** Strategy for pruning excess context */ pruneStrategy: ContextPruneStrategy; } /** * Tool set configuration for a sub-agent. * Restricts capabilities to only what the subtask needs. */ interface ToolSet { /** Allowed capabilities (from AgentCapability values) */ capabilities: string[]; /** Explicit tool restrictions — tool names to exclude */ restrictions?: string[] | undefined; } /** * Reasoning depth hint for model selection. */ type ReasoningDepth = 'minimal' | 'standard' | 'extended'; /** * Model selection for a sub-agent. * Enables per-subtask model optimization (performance-cost tradeoff). */ interface ModelSelection { /** Provider ID (e.g., 'anthropic', 'openai') */ provider?: string | undefined; /** Specific model ID */ modelId?: string | undefined; /** Generation temperature (0-2) */ temperature?: number | undefined; /** Maximum response tokens */ maxTokens?: number | undefined; /** Reasoning depth hint */ reasoning?: ReasoningDepth | undefined; } /** * ICTM configuration tuple. * * Each sub-agent receives a unique ICTM config tailored to its subtask, * enabling dynamic specialization instead of static expert roles. * * @example * ```typescript * const config: ICTMConfig = { * instructions: 'Analyze the authentication module for SQL injection vulnerabilities.', * context: { maxTokens: 8000, relevanceThreshold: 0.7, includeHistory: false, pruneStrategy: 'importance' }, * tools: { capabilities: ['code_review', 'research'], restrictions: ['code_generation'] }, * model: { temperature: 0.1, reasoning: 'extended' }, * }; * ``` */ interface ICTMConfig { /** Task-specific instructions (extends the base system prompt) */ instructions: string; /** Context curation filter */ context: ContextFilter; /** Selected tool capabilities */ tools: ToolSet; /** Model configuration */ model: ModelSelection; /** Optional metadata for tracking/extensions */ metadata?: Record | undefined; } /** * Result of ICTM inference — the inferred config plus reasoning. */ interface ICTMInferenceResult { /** Inferred ICTM configuration */ config: ICTMConfig; /** Reasoning for each ICTM component */ reasoning: { instructions: string; context: string; tools: string; model: string; }; /** Confidence in the inference (0-1) */ confidence: number; } /** * A context item that can be filtered and ranked. */ interface CuratedContextItem { /** Unique item identifier */ id: string; /** Text content */ content: string; /** Estimated token count */ tokenCount: number; /** Timestamp (ms since epoch) for recency scoring */ timestamp: number; /** Relevance score (0-1) assigned during curation */ relevance: number; /** Source category */ source: 'history' | 'knowledge' | 'task' | 'result'; } declare const ContextPruneStrategySchema: z.ZodEnum<{ hybrid: "hybrid"; importance: "importance"; recency: "recency"; }>; declare const ContextFilterSchema: z.ZodObject<{ maxTokens: z.ZodNumber; relevanceThreshold: z.ZodNumber; includeHistory: z.ZodBoolean; pruneStrategy: z.ZodEnum<{ hybrid: "hybrid"; importance: "importance"; recency: "recency"; }>; }, z.core.$strip>; declare const ToolSetSchema: z.ZodObject<{ capabilities: z.ZodArray; restrictions: z.ZodOptional>; }, z.core.$strip>; declare const ReasoningDepthSchema: z.ZodEnum<{ standard: "standard"; minimal: "minimal"; extended: "extended"; }>; declare const ModelSelectionSchema: z.ZodObject<{ provider: z.ZodOptional; modelId: z.ZodOptional; temperature: z.ZodOptional; maxTokens: z.ZodOptional; reasoning: z.ZodOptional>; }, z.core.$strip>; declare const ICTMConfigSchema: z.ZodObject<{ instructions: z.ZodString; context: z.ZodObject<{ maxTokens: z.ZodNumber; relevanceThreshold: z.ZodNumber; includeHistory: z.ZodBoolean; pruneStrategy: z.ZodEnum<{ hybrid: "hybrid"; importance: "importance"; recency: "recency"; }>; }, z.core.$strip>; tools: z.ZodObject<{ capabilities: z.ZodArray; restrictions: z.ZodOptional>; }, z.core.$strip>; model: z.ZodObject<{ provider: z.ZodOptional; modelId: z.ZodOptional; temperature: z.ZodOptional; maxTokens: z.ZodOptional; reasoning: z.ZodOptional>; }, z.core.$strip>; metadata: z.ZodOptional>; }, z.core.$strip>; declare const ICTMInferenceResultSchema: z.ZodObject<{ config: z.ZodObject<{ instructions: z.ZodString; context: z.ZodObject<{ maxTokens: z.ZodNumber; relevanceThreshold: z.ZodNumber; includeHistory: z.ZodBoolean; pruneStrategy: z.ZodEnum<{ hybrid: "hybrid"; importance: "importance"; recency: "recency"; }>; }, z.core.$strip>; tools: z.ZodObject<{ capabilities: z.ZodArray; restrictions: z.ZodOptional>; }, z.core.$strip>; model: z.ZodObject<{ provider: z.ZodOptional; modelId: z.ZodOptional; temperature: z.ZodOptional; maxTokens: z.ZodOptional; reasoning: z.ZodOptional>; }, z.core.$strip>; metadata: z.ZodOptional>; }, z.core.$strip>; reasoning: z.ZodObject<{ instructions: z.ZodString; context: z.ZodString; tools: z.ZodString; model: z.ZodString; }, z.core.$strip>; confidence: z.ZodNumber; }, z.core.$strip>; /** * nexus-agents/agents - TechLead Types and Schemas * * Type definitions and Zod schemas for TechLead agent functionality. * Includes subtask, expert selection, and synthesis types. */ /** * Subtask priority levels. */ type SubtaskPriority = 'critical' | 'high' | 'medium' | 'low'; /** * Subtask status. */ type SubtaskStatus = 'pending' | 'assigned' | 'in_progress' | 'completed' | 'failed'; /** * A subtask broken down from the main task. */ interface SubTask { /** Unique subtask identifier */ id: string; /** Parent task ID */ parentTaskId: string; /** Description of what needs to be done */ description: string; /** Expected output format or type */ expectedOutput: string; /** Dependencies on other subtasks (by ID) */ dependencies: string[]; /** Priority level */ priority: SubtaskPriority; /** Current status */ status: SubtaskStatus; /** Assigned expert role (if any) */ assignedRole?: AgentRole; /** Estimated complexity (1-10) */ complexity: number; /** Required capabilities for this subtask */ requiredCapabilities: string[]; } /** * Result of task analysis. */ interface TaskAnalysis { /** Task ID being analyzed */ taskId: string; /** Overall complexity score (1-10) */ complexity: number; /** Type of task (code, architecture, documentation, etc.) */ taskType: string; /** Key requirements extracted from the task */ requirements: string[]; /** Identified risks or challenges */ risks: string[]; /** Whether task needs decomposition */ needsDecomposition: boolean; /** Recommended approach */ approach: string; /** Estimated total effort in relative units */ estimatedEffort: number; /** * Commit-before-generate block (#1827). * Forces the orchestrator to commit to a direction before dispatching workers, * countering LLM mode-collapse toward safe defaults. Optional for backward * compatibility with older analysis outputs. */ commitment?: TaskCommitment | undefined; } /** * Orchestrator's directional commitment, emitted before decomposition (#1827). * Modeled after the `frontend-design` plugin's Design Thinking pre-phase. */ interface TaskCommitment { /** What this task is fundamentally about (one sentence). */ purpose: string; /** The non-obvious choice being made. */ approach: string; /** What would make the output worse if solved by default patterns. */ differentiation: string; /** Hard limits: deadlines, scope boundaries, invariants. */ constraints: string[]; } /** * Expert assignment for a subtask. */ interface ExpertAssignment { /** Subtask ID */ subtaskId: string; /** Assigned expert role */ expertRole: AgentRole; /** Reason for selection */ selectionReason: string; /** Confidence in the assignment (0-1) */ confidence: number; /** ICTM configuration for dynamic sub-agent creation (Issue #756) */ ictmConfig?: ICTMConfig; } /** * Collaboration metadata for synthesis (Issue #488). */ interface CollaborationMetadata { /** Session ID from collaboration protocol */ sessionId: string; /** Protocol pattern used */ pattern: string; /** Number of participants */ participantCount: number; /** Agreement level (0-1) */ agreementLevel: number; } /** * Synthesis of multiple task results. */ interface SynthesizedResult { /** Combined output from all results */ combinedOutput: string; /** Summary of the synthesis process */ summary: string; /** Individual result summaries */ resultSummaries: ResultSummary[]; /** Any conflicts detected between results */ conflicts: Conflict[]; /** Overall quality assessment */ qualityScore: number; /** Recommendations for follow-up */ recommendations: string[]; /** Collaboration metadata if collaborative synthesis was used (Issue #488) */ collaborationMetadata?: CollaborationMetadata | undefined; } /** * Summary of a single result. */ interface ResultSummary { /** Subtask ID */ subtaskId: string; /** Brief summary of the output */ summary: string; /** Quality of this result (0-1) */ quality: number; /** Key contributions to final output */ contributions: string[]; } /** * Conflict between results. */ interface Conflict { /** First subtask ID */ subtaskId1: string; /** Second subtask ID */ subtaskId2: string; /** Description of the conflict */ description: string; /** How the conflict was resolved */ resolution: string; } /** * Options for the Orchestrator agent (coordination, decomposition, delegation). * * @remarks * Renamed from TechLeadOptions in Issue #759. * The old name is retained as a deprecated type alias. */ interface OrchestratorOptions { /** Maximum number of subtasks to create */ maxSubtasks?: number; /** Minimum complexity to trigger decomposition */ decompositionThreshold?: number; /** Enable parallel execution hints */ enableParallelHints?: boolean; /** Custom expert selection weights */ expertWeights?: Partial>; } /** * Zod schema for SubtaskPriority. */ declare const SubtaskPrioritySchema: z.ZodEnum<{ critical: "critical"; high: "high"; low: "low"; medium: "medium"; }>; /** * Zod schema for SubtaskStatus. */ declare const SubtaskStatusSchema: z.ZodEnum<{ failed: "failed"; completed: "completed"; pending: "pending"; in_progress: "in_progress"; assigned: "assigned"; }>; /** * Zod schema for SubTask. */ declare const SubTaskSchema: z.ZodObject<{ id: z.ZodString; parentTaskId: z.ZodString; description: z.ZodString; expectedOutput: z.ZodString; dependencies: z.ZodArray; priority: z.ZodEnum<{ critical: "critical"; high: "high"; low: "low"; medium: "medium"; }>; status: z.ZodEnum<{ failed: "failed"; completed: "completed"; pending: "pending"; in_progress: "in_progress"; assigned: "assigned"; }>; assignedRole: z.ZodOptional>; complexity: z.ZodNumber; requiredCapabilities: z.ZodArray; }, z.core.$strip>; /** * Zod schema for TaskAnalysis. */ /** * Zod schema for TaskAnalysis. * Uses coercion and transforms for numeric fields because LLMs * may return numbers as strings or descriptive words (Issue #663). */ declare const TaskAnalysisSchema: z.ZodObject<{ taskId: z.ZodString; complexity: z.ZodPipe, z.ZodTransform>; taskType: z.ZodString; requirements: z.ZodArray; risks: z.ZodArray; needsDecomposition: z.ZodPipe, z.ZodTransform>; approach: z.ZodString; estimatedEffort: z.ZodPipe, z.ZodTransform>; commitment: z.ZodOptional; }, z.core.$strip>>; }, z.core.$strip>; /** * Zod schema for ExpertAssignment. */ declare const ExpertAssignmentSchema: z.ZodObject<{ subtaskId: z.ZodString; expertRole: z.ZodEnum<{ custom: "custom"; orchestrator: "orchestrator"; code_expert: "code_expert"; architecture_expert: "architecture_expert"; security_expert: "security_expert"; documentation_expert: "documentation_expert"; testing_expert: "testing_expert"; devops_expert: "devops_expert"; research_expert: "research_expert"; pm_expert: "pm_expert"; ux_expert: "ux_expert"; infrastructure_expert: "infrastructure_expert"; }>; selectionReason: z.ZodString; confidence: z.ZodNumber; ictmConfig: z.ZodOptional; }, z.core.$strip>; tools: z.ZodObject<{ capabilities: z.ZodArray; restrictions: z.ZodOptional>; }, z.core.$strip>; model: z.ZodObject<{ provider: z.ZodOptional; modelId: z.ZodOptional; temperature: z.ZodOptional; maxTokens: z.ZodOptional; reasoning: z.ZodOptional>; }, z.core.$strip>; metadata: z.ZodOptional>; }, z.core.$strip>>; }, z.core.$strip>; /** * Zod schema for SynthesizedResult. */ declare const SynthesizedResultSchema: z.ZodObject<{ combinedOutput: z.ZodString; summary: z.ZodString; resultSummaries: z.ZodArray; }, z.core.$strip>>; conflicts: z.ZodArray>; qualityScore: z.ZodNumber; recommendations: z.ZodArray; collaborationMetadata: z.ZodOptional>; }, z.core.$strip>; /** * Zod schema for OrchestratorOptions. */ declare const OrchestratorOptionsSchema: z.ZodObject<{ maxSubtasks: z.ZodOptional; decompositionThreshold: z.ZodOptional; enableParallelHints: z.ZodOptional; expertWeights: z.ZodOptional>; }, z.core.$strip>; /** * Expert role capabilities mapping. * Maps each expert role to their core capabilities. */ declare const EXPERT_CAPABILITIES: Readonly>; /** * Task type to expert role mapping. * Maps common task types to their primary expert roles. */ declare const TASK_TYPE_EXPERTS: Readonly>; /** * nexus-agents/agents - Plan to Workflow Converter * * Converts Orchestrator ExecutionPlans to WorkflowEngine WorkflowDefinitions. * This "crystallizes" dynamic plans into reusable, static workflows. * * (Source: ARCHITECTURE.md, Plan-to-Workflow Conversion) */ /** * Core execution plan data (without methods). * This represents the pure data from Orchestrator analysis. */ interface ExecutionPlanData { /** The original task ID this plan was created for */ taskId: string; /** Analysis of the task complexity and requirements */ analysis: TaskAnalysis; /** Decomposed subtasks (empty if task didn't need decomposition) */ subtasks: SubTask[]; /** Expert role assignments for each subtask */ assignments: ExpertAssignment[]; /** Groups of subtask IDs that can execute in parallel */ parallelGroups: string[][]; /** Estimated total duration in milliseconds */ estimatedDuration: number; } /** * Options for converting an ExecutionPlan to a WorkflowDefinition. */ interface PlanConversionOptions { /** Workflow name (defaults to taskId) */ name?: string; /** Workflow version (defaults to "1.0.0") */ version?: string; /** Additional description */ description?: string; /** Include original analysis as metadata in description */ includeAnalysis?: boolean; /** Default timeout for steps in ms */ defaultStepTimeout?: number; /** Default retry count for steps */ defaultRetries?: number; /** Input definitions to add to workflow */ inputs?: InputDefinition[]; } /** * nexus-agents/agents - Collaboration Session Helpers * * Helper types and functions for CollaborationSession class. * Extracted to keep the main session class under 400 lines. */ /** Options for creating a CollaborationSession. */ interface CollaborationSessionOptions { logger?: ILogger; onStatusChange?: (status: SessionStatus) => void; onMessage?: (message: CollaborationMessage) => void; roleResolver?: (expertId: string) => AgentRole; /** Optional event bus for cross-session event publishing */ eventBus?: ICollaborationEventBus; } /** Session event types for callbacks. */ type SessionEvent = { type: 'status_change'; status: SessionStatus; } | { type: 'expert_joined'; expertId: string; } | { type: 'result_submitted'; expertId: string; result: TaskResult; } | { type: 'review_completed'; reviewerId: string; approved: boolean; } | { type: 'vote_received'; expertId: string; decision: string; } | { type: 'timeout'; expertId?: string; } | { type: 'error'; error: Error; }; /** * nexus-agents/agents - Collaboration Session * * Manages collaboration sessions between multiple experts. * Handles session lifecycle, message routing, and result collection. */ /** Manages a collaboration session between multiple experts. */ declare class CollaborationSession { private readonly logger; private readonly onStatusChange; private readonly onMessage; private readonly roleResolver; private readonly eventBus; private state; private timeoutHandle; private readonly eventListeners; constructor(options?: CollaborationSessionOptions); /** Starts a new collaboration session. */ start(config: CollaborationConfig): Result; /** Submits a result from an expert. */ submitResult(expertId: string, result: TaskResult): Result; /** Requests a review from one expert to another. */ requestReview(fromExpert: string, toExpert: string, artifact: unknown): Result; /** Submits a review response. */ submitReview(reviewerId: string, requesterId: string, approved: boolean, feedback: string): Result; /** Submits a vote for consensus protocol. */ vote(expertId: string, decision: 'approve' | 'reject' | 'abstain', reasoning: string): Result; getStatus(): SessionState | null; getSessionId(): string | null; /** Marks an expert as failed. */ markExpertFailed(expertId: string, error: string): Result; /** Gets task assignments for experts based on pattern. */ getTaskAssignments(): TaskAssignmentMessage[]; /** Finalizes the session and returns aggregated result. */ finalize(): Result; cancel(reason: string): void; addEventListener(listener: (event: SessionEvent) => void): void; removeEventListener(listener: (event: SessionEvent) => void): void; private setStatus; private logMessage; private startTimeout; private clearTimeout; private checkProgress; private emitEvent; /** Emit an event to the external event bus if configured. */ private emitBusEvent; } declare function createCollaborationSession(options?: CollaborationSessionOptions): CollaborationSession; /** * nexus-agents/agents - Review Collaboration Protocol * * Protocol implementation for review collaboration pattern where * one expert produces work and another reviews it. */ /** * Review collaboration protocol. */ declare class ReviewProtocol implements ICollaborationProtocol { readonly pattern: "review"; protected readonly logger: ILogger; protected session: CollaborationSession | null; protected cancelled: boolean; protected readonly options: ProtocolOptions; constructor(options?: ProtocolOptions); cancel(reason: string): void; execute(config: CollaborationConfig, agents: Map): Promise>; private initReviewSession; private validateAgents; private executeAgentTask; private executeProduction; private executeReview; } /** * nexus-agents/agents - Consensus Collaboration Protocol * * Protocol implementation for consensus-based collaboration pattern where * multiple experts vote on decisions. */ /** * Consensus collaboration protocol. */ declare class ConsensusProtocol implements ICollaborationProtocol { readonly pattern: "consensus"; protected readonly logger: ILogger; protected session: CollaborationSession | null; protected cancelled: boolean; protected readonly options: ProtocolOptions; constructor(options?: ProtocolOptions); cancel(reason: string): void; execute(config: CollaborationConfig, agents: Map): Promise>; private validateAgents; private executeAgentTask; } /** * nexus-agents/agents - Collaboration Protocols * * Protocol implementations for different collaboration patterns: * - Sequential: Experts work in order, passing results forward * - Parallel: Experts work simultaneously * - Review: One expert reviews another's work * - Consensus: Voting-based decision making */ /** * Abstract base class for collaboration protocols. */ declare abstract class BaseProtocol implements ICollaborationProtocol { protected readonly options: ProtocolOptions; abstract readonly pattern: CollaborationConfig['pattern']; protected readonly logger: ILogger; protected session: CollaborationSession | null; protected cancelled: boolean; constructor(options?: ProtocolOptions); abstract execute(config: CollaborationConfig, agents: Map): Promise>; cancel(reason: string): void; protected createSession(): CollaborationSession; protected executeAgentTask(agent: IAgent, task: Task$1, previousResults?: TaskResult[]): Promise>; protected validateAgents(config: CollaborationConfig, agents: Map): Result; } /** * Sequential collaboration protocol. */ declare class SequentialProtocol extends BaseProtocol { readonly pattern: "sequential"; execute(config: CollaborationConfig, agents: Map): Promise>; private initSession; private checkCancelled; private executeSequentialStep; } /** * Parallel collaboration protocol. */ declare class ParallelProtocol extends BaseProtocol { readonly pattern: "parallel"; execute(config: CollaborationConfig, agents: Map): Promise>; } /** * Factory for creating collaboration protocols. */ declare class ProtocolFactory { private readonly options; constructor(options?: ProtocolOptions); create(pattern: CollaborationConfig['pattern']): ICollaborationProtocol; execute(config: CollaborationConfig, agents: Map): Promise>; } /** * Creates a protocol factory. */ declare function createProtocolFactory(options?: ProtocolOptions): ProtocolFactory; /** * Adaptive Protocol Selector * * Automatically selects the optimal collaboration protocol based on task type. * * Based on research from arXiv:2502.19130: * - Voting (parallel) works better for reasoning tasks (+13.2%) * - Consensus works better for knowledge tasks (+2.8%) * * @module agents/collaboration/adaptive-protocol-selector * (Source: Issue #125, arXiv:2502.19130) */ /** Task type alias for protocol mapping keys. */ type TaskType = ReasoningKnowledgeType; /** Classification result from SharedTaskAnalyzer. */ interface ClassificationResult { readonly type: TaskType; readonly confidence: number; } /** * Configuration for adaptive protocol selection. */ interface AdaptiveProtocolConfig { /** Logger instance */ readonly logger?: ILogger; /** Protocol options to pass to factory */ readonly protocolOptions?: ProtocolOptions; /** Classifier configuration */ readonly classifierConfig?: { readonly minConfidence?: number; }; /** Protocol mapping for task types */ readonly protocolMapping?: { readonly reasoning?: CollaborationPattern; readonly knowledge?: CollaborationPattern; readonly unknown?: CollaborationPattern; }; /** Whether to log classification decisions */ readonly logDecisions?: boolean; } /** * Selection result with metadata. */ interface SelectionResult$2 { /** * The pattern that will be used. * * This is always `config.pattern`. `CollaborationPattern` has no `auto` * member, so a caller cannot ask for adaptive selection and adaptation can * never win — see {@link adaptivePattern} for what it would have chosen * (#4833). */ readonly pattern: CollaborationPattern; /** * The pattern adaptation would choose from the task classification (#4833). * * Advisory. Previously computed and discarded, which left the caller unable * to see the one thing this class exists to produce. */ readonly adaptivePattern: CollaborationPattern; /** Classification that led to {@link adaptivePattern}. */ readonly classification: ClassificationResult; /** * Whether the caller's pattern differs from {@link adaptivePattern}. * * A comparison, NOT evidence that a selection was applied and then * overridden — nothing is applied. It was logged as though a live decision * had been made and reversed (#4833). */ readonly wasOverridden: boolean; } /** * Adaptive protocol selector that classifies tasks and recommends protocols. * * Advisory: `selectProtocol` cannot change the protocol in use, because * `CollaborationPattern` has no `auto` member and so a caller has no way to * defer to adaptation. `getRecommendation` reports what adaptation would * choose; acting on it is the caller's decision. * * Whether to add that sentinel so adaptation can win is #4833. Its named * consumer is `TechLeadCollaboration.executeCollaboration`, which currently * declines the recommendation on purpose. */ declare class AdaptiveProtocolSelector { private readonly factory; private readonly analyzer; private readonly config; private readonly log; constructor(config?: AdaptiveProtocolConfig); /** * Classify a task and report which protocol adaptation would choose. * * The returned `pattern` is always `config.pattern`: `CollaborationPattern` * has no `auto` member, so there is no way for a caller to defer to * adaptation. `adaptivePattern` carries the advisory choice (#4833). * * @param config - Collaboration config; its `pattern` is always honoured * @returns The pattern in use, the advisory choice, and the classification */ selectProtocol(config: CollaborationConfig): SelectionResult$2; /** * Execute collaboration with adaptive protocol selection. * * If config.pattern is provided, it will be used as an override. * Otherwise, the optimal protocol is selected based on task type. * * @param config - Collaboration configuration * @param agents - Available agents * @returns Collaboration result */ execute(config: CollaborationConfig, agents: Map): Promise>; /** * Get the recommended protocol for a task without executing. * * Returns the *adaptive* choice. It previously returned `selection.pattern` * — the caller's own input — so the "recommendation" echoed the question * back with reasoning attached that read as an answer (#4833). */ getRecommendation(config: CollaborationConfig): { recommendedPattern: CollaborationPattern; taskType: TaskType; confidence: number; reasoning: string; }; } /** * Orchestrator Collaboration Integration * * Wires collaboration protocols (consensus, aegean, reflexion) into Orchestrator * for enhanced synthesis and complex task coordination. * * @module agents/tech-lead-collaboration * (Source: Issue #488 - Wire collaboration protocols to Orchestrator) */ /** * Configuration for Orchestrator collaboration integration. * * @remarks * Renamed from TechLeadCollaborationConfig in Issue #759. */ interface OrchestratorCollaborationConfig { /** Enable collaboration protocols for synthesis */ readonly enableCollaborativeSynthesis?: boolean; /** Minimum number of experts to trigger collaborative synthesis */ readonly minExpertsForCollaboration?: number; /** Complexity threshold for using collaboration protocols */ readonly complexityThreshold?: number; /** Logger instance */ readonly logger?: ILogger; } /** * Orchestrator collaboration helper. * * Provides methods to use collaboration protocols for: * - Synthesizing results from multiple experts * - Coordinating complex multi-expert tasks * * @remarks * Renamed from TechLeadCollaborationHelper in Issue #759. */ declare class OrchestratorCollaborationHelper { private readonly config; private readonly protocolSelector; private readonly logger; constructor(config?: OrchestratorCollaborationConfig); /** * Check if task should use collaborative synthesis. */ shouldUseCollaboration(analysis: TaskAnalysis, resultCount: number): boolean; /** * Synthesize results using collaboration protocols. * * @param results - Results from multiple experts * @param agents - Map of available agents for collaboration * @param originalTask - The original task being synthesized */ collaborativeSynthesis(results: TaskResult[], agents: Map, originalTask: Task$1): Promise>; /** Build collaboration configuration for synthesis. */ private buildCollabConfig; /** Execute collaboration protocol. */ private executeCollaboration; /** * Get the protocol selector for custom usage. */ getProtocolSelector(): AdaptiveProtocolSelector; } /** * nexus-agents/agents - Orchestrator Agent * * The Orchestrator agent is responsible for: * - Analyzing incoming tasks for complexity and requirements * - Breaking down complex tasks into subtasks * - Selecting appropriate expert agents for subtasks * - Synthesizing results from multiple experts * * @remarks * Renamed from TechLead in Issue #759. The old class name is retained * as a deprecated type alias for backward compatibility. * * (Source: Nexus Agents CLAUDE.md, Agent Architecture) */ /** Extended options for Orchestrator with collaboration. */ interface OrchestratorExtendedOptions { /** Collaboration configuration (Issue #488) */ collaborationConfig?: OrchestratorCollaborationConfig; /** Map of available expert agents for collaboration */ expertAgents?: Map; } /** * Execution plan output structure. * * The ExecutionPlan represents the Orchestrator's analysis and decomposition * of a task. It can optionally be converted to a WorkflowDefinition for * replayable, static execution via the WorkflowEngine. * * ExecutionPlan extends ExecutionPlanData (the pure data) with the * asWorkflowDefinition conversion method. * * @see ARCHITECTURE.md for the separation of concerns between Orchestrator and WorkflowEngine */ interface ExecutionPlan$2 extends ExecutionPlanData { /** * Convert this execution plan to a reusable WorkflowDefinition. * * This "crystallizes" the dynamic plan into a static, replayable workflow * that can be executed by WorkflowEngine. * * @param options - Optional conversion configuration * @returns A valid WorkflowDefinition * * @example * ```typescript * const result = await techLead.execute(task); * const plan = result.value.output as ExecutionPlan; * const workflow = plan.asWorkflowDefinition({ * name: 'my-workflow', * version: '1.0.0', * }); * await workflowEngine.execute(workflow, inputs); * ``` */ asWorkflowDefinition(options?: PlanConversionOptions): WorkflowDefinition; } declare class Orchestrator extends BaseAgent { private readonly orchestratorOptions; private readonly collaborationHelper; private expertAgents; private lastAnalysis?; constructor(options?: Partial & OrchestratorExtendedOptions & { techLeadOptions?: OrchestratorOptions; }); /** * Set expert agents for collaboration (Issue #488). * Call this to provide agents that can participate in collaborative synthesis. */ setExpertAgents(agents: Map): void; /** Execute a task by analyzing, decomposing (if needed), and coordinating. */ protected executeTask(task: Task$1): Promise>; /** Build prompt messages for task execution. */ protected buildPrompt(task: Task$1): Message[]; /** Analyze a task to understand its complexity and requirements. */ analyzeTask(task: Task$1): Promise>; private analyzeTaskWithUsage; /** Decompose a task into subtasks. */ decomposeTask(task: Task$1, analysis: TaskAnalysis): Promise>; private decomposeTaskWithUsage; /** Select appropriate expert agents for each subtask. */ selectExperts(subtasks: SubTask[]): ExpertAssignment[]; /** * Synthesize results from multiple experts into a cohesive output. * * Uses collaboration protocols for complex multi-expert synthesis (Issue #488) * when enough experts and task complexity warrant it. * * @param results - Results to synthesize * @param originalTask - Optional original task for context in collaborative synthesis */ synthesizeResults(results: TaskResult[], originalTask?: Task$1): Promise>; /** Handle empty and single result edge cases. */ private handleSynthesisEdgeCases; /** Try collaborative synthesis if conditions are met. */ private tryCollaborativeSynthesis; /** Perform standard LLM or heuristic synthesis. */ private performStandardSynthesis; /** * Get the collaboration helper for external use. */ getCollaborationHelper(): OrchestratorCollaborationHelper; /** Get the Orchestrator options. */ getOptions(): Readonly>; private buildExecutionPlan; private parseJson; } /** * Creates a new Orchestrator agent with the given options. * This is the preferred factory function for creating coordination agents. * * @param options - Agent configuration options * @returns Orchestrator agent instance * * @example * ```typescript * const orchestrator = createOrchestrator({ * orchestratorOptions: { maxSubtasks: 5 } * }); * const result = await orchestrator.execute(task); * ``` */ declare function createOrchestrator(options?: Partial & { orchestratorOptions?: OrchestratorOptions; }): Orchestrator; /** * nexus-agents/agents - Wave Scheduler Types * * Type definitions for wave-based parallel execution with * concurrency limits, output truncation, and token budget tracking. * * (Source: Issue #769 - Code-enforced subagent context limits) * * @module agents/wave-scheduler-types */ /** * Configuration for the wave scheduler. */ interface WaveSchedulerConfig { /** Maximum number of tasks to execute concurrently in one wave. Default: 4. */ readonly maxConcurrency: number; /** Maximum output length (chars) per task result. Default: 2000. */ readonly maxOutputChars: number; /** * Maximum total token budget across all waves. 0 = unlimited. Default: 0. * * Enforced against the SUM OF ESTIMATES described on * `WaveTaskResult.estimatedTokens`, which excludes input tokens and counts a * failed task as zero. Both errors run in the same direction: the budget * believes it has more headroom than it does, so enabling this does not give * you a reliable spend cap (#4761). */ readonly maxTotalTokens: number; /** Whether to abort remaining waves on first task failure. Default: false. */ readonly abortOnFailure: boolean; /** Timeout per individual task in ms. Default: 60000. */ readonly taskTimeoutMs: number; /** Optional callback invoked after each wave completes. Used for checkpointing. */ readonly onWaveComplete?: (waveIndex: number, results: readonly WaveTaskResult[], cumulativeTokens: number) => Promise; } /** * Default wave scheduler configuration. * Matches CLAUDE.md guidelines: waves of 3-4, 2000 char output budget. */ declare const DEFAULT_WAVE_CONFIG: WaveSchedulerConfig; /** * A task to be executed in a wave. */ interface WaveTask { /** Unique identifier for this task. */ readonly id: string; /** Human-readable description of what this task does. */ readonly description: string; /** The input data for this task. */ readonly input: T; /** IDs of tasks that must complete before this one can start. */ readonly dependencies: readonly string[]; } /** * Result of a single task execution. */ interface WaveTaskResult { /** Task ID this result belongs to. */ readonly taskId: string; /** Whether the task completed successfully. */ readonly success: boolean; /** The output text (truncated to maxOutputChars). */ readonly output: string; /** Whether the output was truncated. */ readonly truncated: boolean; /** Original output length before truncation. */ readonly originalLength: number; /** * Rough token estimate for this task, derived as `outputChars / 4` (#4761). * * NOT a measurement, and specifically NOT comparable to * `ResultMetadata.tokensUsed`: * - **Input is not counted.** Prompt and context usually dominate an agent * task's spend, so a large prompt with a terse answer looks nearly free. * - **A failed task reports 0**, however long it ran before throwing. * * Real usage is not available here: `WaveTaskExecutor` returns a bare string, * so the scheduler has nothing better to sum. Treat this as a coarse * output-size signal, not a spend figure. */ readonly estimatedTokens: number; /** Duration of this task in ms. */ readonly durationMs: number; /** Error message if task failed. */ readonly error?: string; } /** * Result of executing a single wave. */ interface WaveResult { /** The wave index (0-based). */ readonly waveIndex: number; /** Results of all tasks in this wave. */ readonly results: readonly WaveTaskResult[]; /** Total estimated tokens consumed by this wave. */ readonly totalTokens: number; /** Total duration of this wave in ms. */ readonly durationMs: number; } /** * Final result of the full wave execution. */ interface WaveExecutionResult { /** Results organized by wave. */ readonly waves: readonly WaveResult[]; /** All task results flat. */ readonly allResults: readonly WaveTaskResult[]; /** Total estimated tokens consumed across all waves. */ readonly totalTokensUsed: number; /** Total duration in ms. */ readonly totalDurationMs: number; /** Whether execution was aborted early (budget exceeded or failure). */ readonly aborted: boolean; /** Reason for abort, if aborted. */ readonly abortReason?: string; } /** * A chunk of work produced by auto-chunking. */ interface WorkChunk { /** Unique ID for this chunk. */ readonly id: string; /** Scope description (e.g., directory path). */ readonly scope: string; /** Items in this chunk (e.g., file paths). */ readonly items: readonly string[]; } /** * Executor function that processes a single WaveTask. * Returns the output string (which will be truncated by the scheduler). */ type WaveTaskExecutor = (task: WaveTask) => Promise; /** * nexus-agents/agents - Wave Scheduler * * Manages parallel task execution in bounded waves with concurrency limits, * output truncation, and token budget tracking. Prevents agent context * exhaustion by enforcing CLAUDE.md subagent management guidelines. * * (Source: Issue #769 - Code-enforced subagent context limits) * * @module agents/wave-scheduler */ /** * Wave scheduler for bounded parallel task execution. * * Executes tasks in waves respecting concurrency limits, dependency order, * output budgets, and token budgets. Each wave waits for all tasks to * complete before the next wave launches. * * @example * ```typescript * const scheduler = createWaveScheduler({ maxConcurrency: 3 }); * const result = await scheduler.execute(tasks, async (task) => { * return await runAgent(task.input); * }); * console.log(`Completed in ${result.waves.length} waves`); * ``` */ declare class WaveScheduler { private readonly config; private readonly logger; constructor(config?: Partial, logger?: ILogger); /** * Execute tasks in waves respecting dependencies and concurrency limits. */ execute(tasks: readonly WaveTask[], executor: WaveTaskExecutor): Promise; /** * Build waves from tasks respecting dependency ordering. * * Tasks with no unresolved dependencies go in the earliest possible wave. * Within each wave, tasks are further split into sub-waves of maxConcurrency size. */ buildWaves(tasks: readonly WaveTask[]): WaveTask[][]; /** * Get the scheduler configuration. */ getConfig(): Readonly; private runWaveLoop; private isTokenBudgetExhausted; private collectResults; private splitByMaxConcurrency; private executeWave; private executeTask; private withTimeout; } /** * Partition a list of file paths into directory-scoped chunks. * Each chunk corresponds to a top-level directory within the base path. * * @param files - Array of file paths * @param basePath - Base path prefix to strip for grouping * @returns Array of work chunks grouped by top-level directory */ declare function chunkByDirectory(files: readonly string[], basePath: string): WorkChunk[]; /** * Create a new WaveScheduler instance with the given configuration. */ declare function createWaveScheduler(config?: Partial, logger?: ILogger): WaveScheduler; /** * nexus-agents/agents - Expert Base Types * * Base type definitions for expert agents. * Extracted to break circular dependency between expert-types and expert-documentation-types. * * @module agents/experts/expert-base-types * (Source: Issue #392 - Circular dependency resolution) */ /** * Expert-specific configuration options. */ interface ExpertOptions { /** Custom system prompt override */ systemPromptOverride?: string; /** Temperature for completions (domain-specific default if not set) */ temperature?: number; /** Maximum tokens for responses */ maxTokens?: number; /** Enable domain-specific heuristics */ enableHeuristics?: boolean; /** Custom capability extensions */ additionalCapabilities?: AgentCapability[]; } /** * Output format for expert task results. */ interface ExpertOutput { /** Primary result content */ content: string; /** Structured data if applicable */ structuredData?: Record | undefined; /** Recommendations or suggestions */ recommendations?: string[] | undefined; /** Warnings or issues found */ warnings?: string[] | undefined; /** Confidence score (0-1) */ confidence: number; /** Model used for this expert's execution (Issue #817) */ modelUsed?: string | undefined; } /** * nexus-agents/agents - Expert Documentation Types * * Type definitions for documentation-related expert outputs. * Extracted from expert-types.ts to maintain file size limits. */ /** * Documentation result from DocumentationExpert. */ interface DocumentationResult extends ExpertOutput { /** Documentation type */ documentationType: 'api' | 'readme' | 'guide' | 'reference'; /** Generated documentation sections */ sections?: DocumentationSection[] | undefined; /** API documentation */ apiDocs?: ApiDocumentation | undefined; } /** * Documentation section. */ interface DocumentationSection { /** Section title */ title: string; /** Section content */ content: string; /** Subsections */ subsections?: DocumentationSection[]; } /** * API documentation structure. */ interface ApiDocumentation { /** API endpoints or functions */ endpoints: ApiEndpoint[]; /** Data types */ types: ApiType[]; } /** * API endpoint documentation. */ interface ApiEndpoint { /** Endpoint name */ name: string; /** Description */ description: string; /** Parameters */ parameters: Array<{ name: string; type: string; description: string; required: boolean; }>; /** Return type */ returns: { type: string; description: string; }; /** Example usage */ example?: string; } /** * API type documentation. */ interface ApiType { /** Type name */ name: string; /** Description */ description: string; /** Properties */ properties: Array<{ name: string; type: string; description: string; optional: boolean; }>; } /** * nexus-agents/agents - Expert Types and Schemas * * Shared type definitions and Zod schemas for expert agents. * Experts are domain-specialized agents that handle specific task types. */ /** * Expert domain categories. */ type ExpertDomain = 'code' | 'security' | 'architecture' | 'testing' | 'documentation'; /** * Code analysis result from CodeExpert. */ interface CodeAnalysisResult extends ExpertOutput { /** Type of code operation performed */ operationType: 'generation' | 'refactoring' | 'optimization' | 'debugging'; /** Files affected */ affectedFiles?: string[] | undefined; /** Code changes or suggestions */ codeChanges?: CodeChange[] | undefined; } /** * Represents a single code change. */ interface CodeChange { /** File path */ file: string; /** Line number or range */ lineRange?: { start: number; end: number; }; /** Original code */ original?: string; /** Modified code */ modified: string; /** Description of change */ description: string; } /** * Security analysis result from SecurityExpert. */ interface SecurityAnalysisResult extends ExpertOutput { /** Vulnerabilities found */ vulnerabilities: Vulnerability[]; /** * Security score (0-100). When `findingsCoverage === 'unmeasured'`, `securityScore` is `0`: a * fail-closed placeholder and the worst score, so a reader that ignores the marker errs toward * blocking, never toward a clean 100. `partial` scores only the validated findings; `complete` is * unchanged. */ securityScore: number; /** * Coverage of the model-supplied findings after validation. When * `findingsCoverage === 'unmeasured'`, `securityScore` is `0`: a fail-closed placeholder and the * worst score, so a reader that ignores the marker errs toward blocking, never toward a clean * 100. `partial` keeps the score over the validated findings; `complete` is unchanged. */ findingsCoverage?: 'complete' | 'partial' | 'unmeasured' | undefined; /** Compliance status */ compliance?: ComplianceStatus; } /** * Represents a security vulnerability. */ interface Vulnerability { /** Unique vulnerability ID */ id: string; /** Severity level */ severity: 'critical' | 'high' | 'medium' | 'low' | 'info'; /** Vulnerability type (OWASP category) */ type: string; /** Description of the vulnerability */ description: string; /** Affected location */ location?: string; /** Remediation steps */ remediation: string; /** CWE reference if applicable */ cweId?: string; } /** * Compliance check status. */ interface ComplianceStatus { /** Compliance framework */ framework: string; /** Overall status */ status: 'compliant' | 'partial' | 'non-compliant'; /** Specific findings */ findings: string[]; } /** * Architecture analysis result from ArchitectureExpert. */ interface ArchitectureAnalysisResult extends ExpertOutput { /** Analysis type */ analysisType: 'design' | 'review' | 'pattern_selection'; /** Identified patterns */ patterns?: ArchitecturePattern[] | undefined; /** Design decisions */ decisions?: ArchitectureDecision[] | undefined; /** System components */ components?: SystemComponent[] | undefined; } /** * Architecture pattern identification. */ interface ArchitecturePattern { /** Pattern name */ name: string; /** Pattern category */ category: string; /** Applicability score (0-1) */ applicability: number; /** Trade-offs */ tradeoffs: { pros: string[]; cons: string[]; }; } /** * Architecture decision record. */ interface ArchitectureDecision { /** Decision ID */ id: string; /** Decision title */ title: string; /** Context */ context: string; /** Decision made */ decision: string; /** Consequences */ consequences: string[]; /** Status */ status: 'proposed' | 'accepted' | 'deprecated' | 'superseded'; } /** * System component in architecture. */ interface SystemComponent { /** Component name */ name: string; /** Component type */ type: string; /** Responsibilities */ responsibilities: string[]; /** Dependencies */ dependencies: string[]; } /** * Testing analysis result from TestingExpert. */ interface TestingAnalysisResult extends ExpertOutput { /** Operation type */ operationType: 'generation' | 'coverage_analysis' | 'quality_assessment'; /** Generated tests */ tests?: GeneratedTest[] | undefined; /** Coverage metrics */ coverage?: CoverageMetrics | undefined; /** Test quality assessment */ quality?: TestQuality | undefined; } /** * Generated test case. */ interface GeneratedTest { /** Test name */ name: string; /** Test type */ type: 'unit' | 'integration' | 'e2e'; /** Test code */ code: string; /** Target function/component */ target: string; /** Test scenarios covered */ scenarios: string[]; } /** * Code coverage metrics. */ interface CoverageMetrics { /** Line coverage percentage */ line: number; /** Branch coverage percentage */ branch: number; /** Function coverage percentage */ function: number; /** Statement coverage percentage */ statement: number; /** Uncovered areas */ uncoveredAreas?: string[]; } /** * Test quality assessment. */ interface TestQuality { /** Overall score (0-100) */ score: number; /** Test isolation */ isolation: 'good' | 'fair' | 'poor'; /** Assertion quality */ assertionQuality: 'good' | 'fair' | 'poor'; /** Issues found */ issues: string[]; } /** * Expert domain schema. */ declare const ExpertDomainSchema: z.ZodEnum<{ code: "code"; security: "security"; architecture: "architecture"; documentation: "documentation"; testing: "testing"; }>; /** * Expert options schema. */ declare const ExpertOptionsSchema: z.ZodObject<{ systemPromptOverride: z.ZodOptional; temperature: z.ZodOptional; maxTokens: z.ZodOptional; enableHeuristics: z.ZodOptional; additionalCapabilities: z.ZodOptional>; }, z.core.$strip>; /** * Expert output schema. */ declare const ExpertOutputSchema: z.ZodObject<{ content: z.ZodString; structuredData: z.ZodOptional>; recommendations: z.ZodOptional>; warnings: z.ZodOptional>; confidence: z.ZodNumber; }, z.core.$strip>; /** * Vulnerability severity schema. */ declare const VulnerabilitySeveritySchema: z.ZodEnum<{ info: "info"; critical: "critical"; high: "high"; low: "low"; medium: "medium"; }>; /** * Vulnerability schema. */ declare const VulnerabilitySchema: z.ZodObject<{ id: z.ZodString; severity: z.ZodEnum<{ info: "info"; critical: "critical"; high: "high"; low: "low"; medium: "medium"; }>; type: z.ZodString; description: z.ZodString; location: z.ZodOptional; remediation: z.ZodString; cweId: z.ZodOptional; }, z.core.$strip>; /** * Code change schema. */ declare const CodeChangeSchema: z.ZodObject<{ file: z.ZodString; lineRange: z.ZodOptional>; original: z.ZodOptional; modified: z.ZodString; description: z.ZodString; }, z.core.$strip>; /** * Generated test schema. */ declare const GeneratedTestSchema: z.ZodObject<{ name: z.ZodString; type: z.ZodEnum<{ integration: "integration"; e2e: "e2e"; unit: "unit"; }>; code: z.ZodString; target: z.ZodString; scenarios: z.ZodArray; }, z.core.$strip>; /** * Coverage metrics schema. */ declare const CoverageMetricsSchema: z.ZodObject<{ line: z.ZodNumber; branch: z.ZodNumber; function: z.ZodNumber; statement: z.ZodNumber; uncoveredAreas: z.ZodOptional>; }, z.core.$strip>; /** * Default temperatures for each expert domain. */ declare const EXPERT_DEFAULT_TEMPERATURES: Record; /** * Default capabilities for each expert role. */ declare const EXPERT_DEFAULT_CAPABILITIES: Record; /** * nexus-agents/agents - CodeExpert Helper Functions * * Extracted helper functions for CodeExpert to keep the main file under 400 lines. */ /** * Configuration options for CodeExpert. */ interface CodeExpertOptions extends ExpertOptions { /** Enable strict type checking recommendations */ strictTypes?: boolean; /** Preferred code style (if applicable) */ codeStyle?: 'functional' | 'object-oriented' | 'mixed'; /** Target language for code generation */ targetLanguage?: string; } /** * nexus-agents/agents - CodeExpert * * Expert agent specialized in code generation, refactoring, optimization, * and debugging. Uses low temperature (0.2-0.3) for precise code output. * * Capabilities: * - code_generation: Generate new code from specifications * - refactoring: Improve existing code structure * - optimization: Enhance performance * - debugging: Identify and fix bugs */ /** * CodeExpert - Expert agent for code-related tasks. * * Specialized in: * - Code generation from specifications * - Code refactoring and cleanup * - Performance optimization * - Bug detection and debugging */ declare class CodeExpert extends BaseAgent { private readonly expertOptions; constructor(options?: Partial & { expertOptions?: CodeExpertOptions; }); /** * Execute a code-related task. */ protected executeTask(task: Task$1): Promise>; /** * Build prompt messages for the task. */ protected buildPrompt(task: Task$1): Message[]; /** * Get the expert options. */ getExpertOptions(): Readonly; /** * Execute task with heuristic analysis (no model). */ private executeHeuristic; /** * Execute task with model adapter. */ private executeWithModel; /** * Build context information from task. */ private buildContextInfo; /** * Create a heuristic result without model. */ private createHeuristicResult; /** * Extract text content from completion response. */ private extractTextContent; } /** * Creates a new CodeExpert agent with the given options. */ declare function createCodeExpert(options?: Partial & { expertOptions?: CodeExpertOptions; }): CodeExpert; /** * nexus-agents/agents - SecurityExpert * * Expert agent specialized in security review, vulnerability detection, * and security hardening. Uses temperature 0.3 for precise analysis. */ /** * Configuration options for SecurityExpert. */ interface SecurityExpertOptions extends ExpertOptions { /** Compliance frameworks to check */ complianceFrameworks?: string[]; /** Minimum severity to report */ minSeverity?: 'critical' | 'high' | 'medium' | 'low' | 'info'; /** Enable detailed CWE mappings */ enableCweMapping?: boolean; /** Security focus areas */ focusAreas?: SecurityFocusArea[]; } /** * Security focus areas for targeted analysis. */ type SecurityFocusArea = 'authentication' | 'authorization' | 'input_validation' | 'cryptography' | 'injection' | 'secrets' | 'dependencies'; /** * SecurityExpert - Expert agent for security-related tasks. */ declare class SecurityExpert extends BaseAgent { private readonly expertOptions; constructor(options?: Partial & { expertOptions?: SecurityExpertOptions; }); protected executeTask(task: Task$1): Promise>; protected buildPrompt(task: Task$1): Message[]; getExpertOptions(): Readonly; private executeHeuristic; private executeWithModel; private buildContextInfo; private extractTextContent; } declare function createSecurityExpert(options?: Partial & { expertOptions?: SecurityExpertOptions; }): SecurityExpert; /** * nexus-agents/agents - ArchitectureExpert * * Expert agent specialized in system design, design patterns, * and architecture decisions. Uses temperature 0.5 for balanced creativity. */ /** * Configuration options for ArchitectureExpert. */ interface ArchitectureExpertOptions extends ExpertOptions { /** Preferred architecture styles */ preferredStyles?: ArchitectureStyle[]; /** Generate ADRs automatically */ generateADRs?: boolean; /** Include C4 diagram suggestions */ includeC4Suggestions?: boolean; /** Quality attributes to prioritize */ qualityPriorities?: QualityAttribute[]; } /** * Architecture style options. */ type ArchitectureStyle = 'layered' | 'microservices' | 'event_driven' | 'hexagonal' | 'clean' | 'cqrs' | 'ddd'; /** * Quality attributes for architecture decisions. */ type QualityAttribute = 'performance' | 'scalability' | 'maintainability' | 'security' | 'reliability' | 'testability'; /** * ArchitectureExpert - Expert agent for architecture-related tasks. */ declare class ArchitectureExpert extends BaseAgent { private readonly expertOptions; constructor(options?: Partial & { expertOptions?: ArchitectureExpertOptions; }); protected executeTask(task: Task$1): Promise>; protected buildPrompt(task: Task$1): Message[]; getExpertOptions(): Readonly; private executeHeuristic; private executeWithModel; private buildContextInfo; private extractTextContent; } declare function createArchitectureExpert(options?: Partial & { expertOptions?: ArchitectureExpertOptions; }): ArchitectureExpert; /** * nexus-agents/agents - TestingExpert * * Expert agent specialized in test generation, coverage analysis, * and quality assurance. Uses temperature 0.3 for precise test output. */ /** * Configuration options for TestingExpert. */ interface TestingExpertOptions extends ExpertOptions { /** Preferred testing framework */ framework?: 'vitest' | 'jest' | 'mocha' | 'playwright' | 'cypress'; /** Target coverage percentage */ targetCoverage?: number; /** Include mocking strategies */ includeMocking?: boolean; /** Test style preference */ testStyle?: 'bdd' | 'tdd' | 'behavioral'; /** Generate test data factories */ generateFactories?: boolean; } /** * TestingExpert - Expert agent for testing-related tasks. */ declare class TestingExpert extends BaseAgent { private readonly expertOptions; constructor(options?: Partial & { expertOptions?: TestingExpertOptions; }); protected executeTask(task: Task$1): Promise>; protected buildPrompt(task: Task$1): Message[]; getExpertOptions(): Readonly; private executeHeuristic; private executeWithModel; private buildContextInfo; private generateHeuristicTests; private extractTextContent; } declare function createTestingExpert(options?: Partial & { expertOptions?: TestingExpertOptions; }): TestingExpert; /** * nexus-agents/agents - DocumentationExpert * * Expert agent specialized in documentation generation, API documentation, * and README creation. Uses temperature 0.4 for clear yet engaging content. */ /** * Configuration options for DocumentationExpert. */ interface DocumentationExpertOptions extends ExpertOptions { /** Documentation format */ format?: 'markdown' | 'jsdoc' | 'tsdoc' | 'rst'; /** Include code examples */ includeExamples?: boolean; /** Target audience level */ audienceLevel?: 'beginner' | 'intermediate' | 'advanced'; /** Generate table of contents */ generateTOC?: boolean; /** Include badges in README */ includeBadges?: boolean; } /** * DocumentationExpert - Expert agent for documentation-related tasks. */ declare class DocumentationExpert extends BaseAgent { private readonly expertOptions; constructor(options?: Partial & { expertOptions?: DocumentationExpertOptions; }); protected executeTask(task: Task$1): Promise>; protected buildPrompt(task: Task$1): Message[]; getExpertOptions(): Readonly; private executeHeuristic; private executeWithModel; private buildContextInfo; private extractTextContent; } declare function createDocumentationExpert(options?: Partial & { expertOptions?: DocumentationExpertOptions; }): DocumentationExpert; /** * nexus-agents/agents - Expert Configuration * * Configuration schema and types for dynamically creating expert agents. * Experts are specialized agents with specific capabilities and prompts. * 12 built-in expert definitions — cohesive, single-concern file. */ /** * Model preference configuration for an expert. */ interface ModelPreference { /** Provider ID (e.g., 'anthropic', 'openai') */ provider?: string; /** Specific model ID */ modelId?: string; /** Temperature for generation (0.0 - 2.0) */ temperature?: number; /** Maximum tokens for responses */ maxTokens?: number; } /** * Configuration for creating a dynamic expert agent. */ interface ExpertConfig { /** Unique identifier for this expert */ id: string; /** Human-readable name */ name: string; /** Role classification */ role: AgentRole; /** System prompt defining the expert's behavior */ systemPrompt: string; /** List of capabilities this expert has */ capabilities: AgentCapability[]; /** Optional model preferences */ modelPreference?: ModelPreference; /** Optional tool restrictions (allowlist/denylist per role) */ toolRestrictions?: ToolRestrictions; /** Optional metadata for extensions */ metadata?: Record; } /** * Built-in expert type identifiers. */ type BuiltInExpertType = 'code' | 'architecture' | 'security' | 'documentation' | 'testing' | 'devops' | 'research' | 'pm' | 'ux' | 'infrastructure' | 'qa' | 'data-visualization'; /** * Zod schema for ModelPreference. */ declare const ModelPreferenceSchema: z.ZodObject<{ provider: z.ZodOptional; modelId: z.ZodOptional; temperature: z.ZodOptional; maxTokens: z.ZodOptional; }, z.core.$strip>; /** * Zod schema for ExpertConfig. */ /** * Tool restriction configuration for expert roles. * Inspired by Augment Code's subagent tool access control. * Allowlist takes priority — if set, only listed tools are available. * Denylist blocks specific tools (used when allowlist is not set). */ declare const ToolRestrictionsSchema: z.ZodOptional>; deniedTools: z.ZodOptional>; }, z.core.$strip>>; type ToolRestrictions = z.infer; declare const ExpertConfigSchema: z.ZodObject<{ id: z.ZodString; name: z.ZodString; role: z.ZodEnum<{ custom: "custom"; orchestrator: "orchestrator"; code_expert: "code_expert"; architecture_expert: "architecture_expert"; security_expert: "security_expert"; documentation_expert: "documentation_expert"; testing_expert: "testing_expert"; devops_expert: "devops_expert"; research_expert: "research_expert"; pm_expert: "pm_expert"; ux_expert: "ux_expert"; infrastructure_expert: "infrastructure_expert"; qa_expert: "qa_expert"; data_visualization_expert: "data_visualization_expert"; }>; systemPrompt: z.ZodString; capabilities: z.ZodArray>; modelPreference: z.ZodOptional; modelId: z.ZodOptional; temperature: z.ZodOptional; maxTokens: z.ZodOptional; }, z.core.$strip>>; toolRestrictions: z.ZodOptional>; deniedTools: z.ZodOptional>; }, z.core.$strip>>; metadata: z.ZodOptional>; }, z.core.$strip>; /** * Zod schema for BuiltInExpertType. * * MUST stay in lockstep with the `BuiltInExpertType` type union above. * Tested by `BuiltInExpertTypeSchema accepts every literal in BuiltInExpertType` * in expert-config.test.ts to prevent drift (#2338). */ declare const BuiltInExpertTypeSchema: z.ZodEnum<{ code: "code"; security: "security"; architecture: "architecture"; research: "research"; documentation: "documentation"; testing: "testing"; devops: "devops"; infrastructure: "infrastructure"; qa: "qa"; pm: "pm"; ux: "ux"; "data-visualization": "data-visualization"; }>; /** * Built-in expert configurations. * These provide sensible defaults for common expert types. * * MIRROR of `agents/-expert.md`, which is repo-only and NOT shipped — * `package.json#files` lists `dist`, two `src/` asset dirs and the README, so an * installed package has no `agents/` directory. The runtime reads this constant, * never those files, which is why the omission is correct rather than a bug * (#5143). * * GATED BY `scripts/generate-agents-index.ts --check`, which fails when an * expert exists in one place and not the other. Without that gate this constant * and its source documents would drift silently, and the drift would only be * visible to someone reading both. */ declare const BUILT_IN_EXPERTS: Readonly>; /** * Maps built-in expert types to their AgentRole. */ declare const EXPERT_TYPE_TO_ROLE: Readonly>; /** * Validates an expert configuration. * @param config - Configuration to validate * @returns Parsed config or throws on validation error */ declare function validateExpertConfig(config: unknown): ExpertConfig; /** * Safely validates an expert configuration. * @param config - Configuration to validate * @returns Safe parse result with success/error */ declare function safeValidateExpertConfig(config: unknown): { success: true; data: ExpertConfig; } | { success: false; error: z.ZodError; }; /** * nexus-agents/agents/experts - Expert Agent * * The concrete {@link Expert} agent class, extracted from `expert-factory.ts` * so that both the factory and the opt-in recovery wrapper * ({@link ./expert-recovery.ts | RecoverableExpert}) can extend/reference it * without a factory↔recovery import cycle (#4286). */ /** * Expert agent extending SimpleAgent with configuration-based setup. */ declare class Expert extends SimpleAgent { readonly expertConfig: ExpertConfig; constructor(options: BaseAgentOptions, config: ExpertConfig); /** * Get the expert's name. */ get name(): string; /** * Get the expert's metadata. */ get metadata(): Record | undefined; } /** * nexus-agents/agents/resilience - Failure Types * * Type definitions for agent failure archetypes based on arxiv:2512.07497. * Defines four primary failure patterns: premature action, over-helpfulness, * context pollution, and fragile execution. */ /** * The four primary agent failure archetypes from arxiv:2512.07497. */ type FailureArchetype = 'premature_action' | 'over_helpfulness' | 'context_pollution' | 'fragile_execution'; /** * Severity levels for detected failures. */ type FailureSeverity = 'low' | 'medium' | 'high' | 'critical'; /** * A detected failure instance with archetype and context. */ interface DetectedFailure { readonly archetype: FailureArchetype; readonly severity: FailureSeverity; readonly description: string; readonly indicators: readonly string[]; readonly confidence: number; readonly timestamp: number; readonly context?: Record; } /** * Detection result from analyzing agent behavior. */ interface DetectionResult { readonly hasFailure: boolean; readonly failures: readonly DetectedFailure[]; readonly analysisMetadata: { readonly durationMs: number; readonly checksPerformed: number; readonly contentAnalyzed: number; }; } /** * Configuration for failure detection. */ interface DetectorConfig { readonly enabledArchetypes: readonly FailureArchetype[]; readonly confidenceThreshold: number; readonly maxHistoryItems: number; readonly enableHeuristics: boolean; } /** * nexus-agents/agents/resilience - Failure Detector * * Detects agent failure archetypes from arxiv:2512.07497 by analyzing * agent behavior, outputs, and execution patterns. */ /** Input for failure detection analysis. */ interface DetectionInput { readonly messages: readonly Message[]; readonly toolCalls?: readonly ToolCallRecord[]; readonly output?: unknown; readonly taskDescription?: string; } /** Record of a tool call for analysis. */ interface ToolCallRecord { readonly name: string; readonly input: unknown; readonly output?: unknown; readonly success: boolean; readonly errorMessage?: string; } /** * Failure detector that analyzes agent behavior for failure archetypes. */ declare class FailureDetector { private readonly config; private readonly logger; constructor(config?: Partial, logger?: ILogger); /** * Analyzes agent behavior for failure archetypes. */ detect(input: DetectionInput): DetectionResult; /** Detects a specific archetype in the input. */ private detectArchetype; /** Detects premature action failure pattern. */ private detectPrematureAction; /** Detects over-helpfulness failure pattern. */ private detectOverHelpfulness; /** Detects context pollution failure pattern. */ private detectContextPollution; /** Detects fragile execution failure pattern. */ private detectFragileExecution; /** Extracts text content from messages. */ private extractTextContent; /** Counts approximate topic shifts in messages. */ private countTopicShifts; /** Finds tool calls that are repeated (possible retry loops). */ private findRepeatedCalls; /** Creates a detected failure object. */ private createFailure; /** Gets human-readable description for archetype. */ private getArchetypeDescription; } /** * nexus-agents/agents/experts - Expert Execution Recovery (#4286) * * Wires the resilience {@link FailureDetector} + {@link RecoveryManager} into an * opt-in expert-execution recovery policy. {@link RecoverableExpert} overrides * `execute()` to wrap the base run in the canonical `withRetry` primitive * (adapters/retry.ts) with a transient-vs-permanent classification predicate: * * 1. caller cancellation (`options.signal` aborted) → PERMANENT * 2. transport-retryable (429/408/5xx/network/NexusError) → TRANSIENT * 3. behavioral archetype (arxiv:2512.07497) → per-strategy action * 4. otherwise → PERMANENT (fail closed) * * PRIMARY shipped behavior is transport retry (step 2): the common recoverable * case is a transient 429/5xx/network blip. The archetype path (step 3) is a * SECONDARY guidance channel that only fires when the error cause-chain TEXT * carries ≥2 independent indicator families (see * {@link EXPERT_ERROR_TEXT_CONFIDENCE_THRESHOLD}); a lone one-family signal * (e.g. a 401 "Invalid API key") stays permanent and fails closed. * * The retry loop, backoff, and jitter are NOT reimplemented here — they are the * shared `withRetry`/`isRetryableError` primitives (adapters/retry.ts:9-19 * forbids a third retry loop). Delay/attempt knobs default to * `DEFAULT_RETRY_CONFIG` (derived from config/defaults.ts RETRY_DEFAULTS). */ /** * Opt-in recovery policy attached to an expert at creation time. All fields are * optional and fall through to {@link DEFAULT_RETRY_CONFIG} (retry knobs) and * this module's detector defaults. */ interface ExpertRecoveryPolicy { /** * Maximum retries (attempts = maxRetries + 1). Default: * {@link EXPERT_RECOVERY_DEFAULT_MAX_RETRIES} (1 → 2 attempts), NOT * DEFAULT_RETRY_CONFIG.maxRetries (3). */ maxRetries?: number; /** Base backoff delay (ms). Default: DEFAULT_RETRY_CONFIG. */ baseDelayMs?: number; /** Maximum backoff delay (ms). Default: DEFAULT_RETRY_CONFIG. */ maxDelayMs?: number; /** Jitter factor (0-1). Default: DEFAULT_RETRY_CONFIG. */ jitterFactor?: number; /** Override the failure detector configuration. */ detectorConfig?: Partial; } /** * The outcome of classifying a single failed execution attempt. * - `transient`: retry (transport error, or a recoverable behavioral archetype) * - `permanent`: fail closed (cancelled, non-retryable, or a terminal archetype) */ type FailureClassification = { kind: 'transient' | 'permanent'; source: 'transport' | 'archetype' | 'default'; archetype?: FailureArchetype; confidence?: number; }; /** * Classifies a single failed execution attempt as transient or permanent. * * See the module header for the ordered decision procedure. `signal` is checked * first (mandatory guard): RETRYABLE_ERROR_PATTERNS matches /aborted/i, so * without this a cancelled task would otherwise be retried. * * Fails CLOSED on a throwing classifier (#4303): the body reads `error.message` * and walks `.cause` (via getErrorMessage/extractErrorMessage/isRetryableErrorChain) * and calls `detector.detect`. An Error-like object with a throwing `.message` or * `.cause` getter would make any of those throw. `execute()` runs this INSIDE * `withRetry`'s isRetryable predicate and again in annotateExhausted, neither of * which is try-guarded by withRetry (adapters/retry.ts:339-363 catches only * `operation()`), so an escaping throw would reject the `Promise>` and * break the never-throws contract `execute_expert` relies on. This single outer * guard covers BOTH call sites: any throw during classification → permanent. */ declare function classifyExpertFailure(error: unknown, detector: FailureDetector, taskDescription?: string, signal?: AbortSignal): FailureClassification; /** * An {@link Expert} whose `execute()` applies a transient-vs-permanent recovery * policy. Wrapping at `execute()` (not `executeTask()`) reuses the base * state-machine auto-reset (#1060) and per-attempt heartbeat/timeout. */ declare class RecoverableExpert extends Expert { private readonly detector; private readonly recoveryManager; private readonly recoveryConfig; private readonly recoveryLogger; constructor(options: BaseAgentOptions, config: ExpertConfig, policy: ExpertRecoveryPolicy); execute(task: Task$1, options?: { signal?: AbortSignal; }): Promise>; /** * Per-retry callback: logs the attempt and, for a recoverable archetype, * injects archetype-specific guidance into the next attempt's task. * * Returns the (possibly augmented) task. onRetry runs INSIDE withRetry's catch * but is NOT itself try-guarded (adapters/retry.ts:352-359 — the try wraps only * `operation()`), so a throw here would escape withRetry and reject the Promise. * The guidance path re-reads the error (extractErrorMessage) and calls * detector.detect, so a pathological error (#4303 throwing getter) could throw — * guard it: on failure, skip injection and retry with the un-augmented task. */ private handleRetry; /** * Builds the annotated failure returned when recovery is exhausted. withRetry * skips isRetryable on the final attempt, so the per-attempt `lastClassification` * can be stale (or undefined for maxRetries:0). Re-classify the actual `lastError` * so the recovery trace labels the failure that was truly returned. */ private annotateExhausted; /** Appends archetype recovery guidance to a mutable copy of the task. */ private injectRecoveryGuidance; /** Recovers the DetectedFailure for an archetype (re-detect, else synthesize). */ private buildDetectedFailure; } /** * nexus-agents/agents - Expert Factory * * Factory for creating expert agents from configuration. * Supports both built-in expert types and custom configurations. */ /** * Error specific to factory operations. */ declare class FactoryError extends AgentError$1 { constructor(message: string, options?: { cause?: Error; context?: Record; }); } /** * Options for creating an expert. * (Source: Issue #476 - Wire context pruning to ExpertFactory) */ interface CreateExpertOptions { /** Model adapter to use */ adapter?: IModelAdapter; /** Override model preferences from config */ modelOverrides?: Partial; /** Additional capabilities to add */ additionalCapabilities?: AgentCapability[]; /** * Context pruning configuration (Issue #476). * Enables automatic memory management for long-running conversations. * Since Issue #479, context pruning is enabled by default. */ contextPruning?: ContextPrunerAgentConfig; /** * Opt-in transient-vs-permanent execution recovery policy (#4286). * * When present, `createExpert` returns a {@link RecoverableExpert} whose * `execute()` retries transient failures (transport 429/5xx/network errors, * and archetype failures classified as recoverable) with exponential backoff, * and fails closed on permanent failures. When ABSENT, a plain {@link Expert} * is constructed and behavior is bit-for-bit identical to the pre-#4286 path. */ recoveryPolicy?: ExpertRecoveryPolicy; } /** * Create an expert agent from a configuration object. * * @param config - Expert configuration * @param options - Creation options including adapter * @returns Result with Expert or FactoryError * * @example * ```typescript * const config: ExpertConfig = { * id: 'my-expert', * name: 'My Expert', * role: 'code_expert', * capabilities: ['task_execution'], * systemPrompt: 'You are a code review expert.', * }; * const result = createExpert(config, { adapter: myAdapter }); * if (result.ok) { * const expert = result.value; * } * ``` */ declare function createExpert(config: ExpertConfig, options?: CreateExpertOptions): Result; /** * Create a built-in expert by type. * * Built-in types include: 'code', 'architecture', 'security', * 'documentation', and 'testing'. * * @param type - Built-in expert type * @param options - Creation options including adapter * @returns Result with Expert or FactoryError * * @example * ```typescript * const result = createBuiltInExpert('security', { adapter: myAdapter }); * if (result.ok) { * const securityExpert = result.value; * } * ``` */ declare function createBuiltInExpert(type: BuiltInExpertType, options?: CreateExpertOptions): Result; /** * Create multiple experts from configurations. * * @param configs - Array of expert configurations * @param options - Creation options applied to all experts * @returns Result with array of Experts or first FactoryError */ declare function createManyExperts(configs: ExpertConfig[], options?: CreateExpertOptions): Result; /** * Create all built-in experts. * * @param options - Creation options applied to all experts * @returns Result with array of all built-in Experts */ declare function createAllBuiltInExperts(options?: CreateExpertOptions): Result; /** * Validate a configuration without creating an expert. * * @param config - Configuration to validate * @returns Result with validated config or FactoryError */ declare function validateExpertConfigStrict(config: unknown): Result; /** * Get the configuration for a built-in expert type. * * @param type - Built-in expert type * @returns Result with config or FactoryError if type invalid */ declare function getBuiltInExpertConfig(type: BuiltInExpertType): Result; /** * Create an expert agent from an ICTM configuration (Issue #756). * * Bridges the ICTM pattern to the existing expert factory by converting * the ICTM config to an ExpertConfig and delegating to createExpert(). * * @param ictm - ICTM configuration with instructions, context, tools, model * @param subtaskId - Subtask identifier used for naming * @param options - Creation options including adapter * @returns Result with Expert or FactoryError */ declare function createFromICTM(ictm: ICTMConfig, subtaskId: string, options?: CreateExpertOptions): Result; /** * Factory namespace for creating expert agents. * Provides static methods for backward compatibility. */ declare const ExpertFactory: { readonly create: typeof createExpert; readonly createBuiltIn: typeof createBuiltInExpert; readonly createMany: typeof createManyExperts; readonly createAllBuiltIn: typeof createAllBuiltInExperts; readonly validate: typeof validateExpertConfigStrict; readonly getBuiltInConfig: typeof getBuiltInExpertConfig; readonly createFromICTM: typeof createFromICTM; }; /** * nexus-agents/agents - Expert Registry * * Singleton registry for managing expert agents. * Provides registration, lookup, and query capabilities. * * Implements IRegistry for unified registry API. * (Source: ADR-0012 - Registry API Unification) */ /** * Error specific to registry operations. */ declare class RegistryError extends AgentError$1 { constructor(message: string, options?: { cause?: Error; context?: Record; }); } /** * Options for registering an expert. */ interface RegisterOptions { /** Whether to replace if expert with same ID exists */ replace?: boolean; } /** * Query options for finding experts. */ interface QueryOptions { /** Filter by role */ role?: string; /** Filter by capability (expert must have all specified) */ capabilities?: AgentCapability[]; /** Filter by capability (expert must have at least one) */ anyCapability?: AgentCapability[]; /** Maximum number of results */ limit?: number; } /** * Statistics about the registry. * Extends IRegistryStats for interface compatibility (ADR-0012). */ interface RegistryStats extends IRegistryStats { /** Total number of registered experts (IRegistryStats alias) */ total: number; /** Count by role */ byRole: Record; /** Count by capability */ byCapability: Record; } /** * Singleton registry for managing expert agents. * * Provides thread-safe registration and lookup of experts. * Supports querying by ID, role, and capabilities. * * Implements IRegistry for unified registry API. */ declare class ExpertRegistry$1 implements IRegistry { private static instance; private readonly experts; private constructor(); /** * Get the singleton instance. */ static getInstance(): ExpertRegistry$1; /** * Reset the singleton instance (for testing). */ static resetInstance(): void; /** * Register an expert in the registry. * * @param expert - Expert to register * @param options - Registration options * @returns Result with void or RegistryError */ register(expert: Expert, options?: RegisterOptions): Result; /** * Register multiple experts. * * @param experts - Experts to register * @param options - Registration options * @returns Result with void or first RegistryError */ registerMany(experts: Expert[], options?: RegisterOptions): Result; /** * Unregister an expert by ID. * * @param id - Expert ID to unregister * @returns Result with the removed Expert or RegistryError */ unregister(id: string): Result; /** * Get an expert by ID. * * @param id - Expert ID to retrieve * @returns Result with Expert or RegistryError */ get(id: string): Result; /** * Check if an expert is registered. * * @param id - Expert ID to check * @returns True if expert is registered */ has(id: string): boolean; /** * Get experts by capability. * * Returns all experts that have the specified capability. * * @param capability - Capability to search for * @returns Array of matching experts */ getByCapability(capability: AgentCapability): Expert[]; /** * Get experts by role. * * @param role - Role to search for * @returns Array of matching experts */ getByRole(role: string): Expert[]; /** * Query experts with multiple criteria. * Domain-specific query with structured options. * * @param options - Query options * @returns Array of matching experts */ queryWithOptions(options: QueryOptions): Expert[]; /** * Query experts with predicate function. * IRegistry interface method. * * @param predicate - Function to test each expert * @returns Array of matching experts */ query(predicate: (item: Expert) => boolean): Expert[]; /** * Get all registered experts. * IRegistry interface method. * * @returns Array of all registered experts */ getAll(): Expert[]; /** * Get all registered expert IDs. * IRegistry interface method. * * @returns Array of all registered expert IDs */ getAllIds(): string[]; /** * Search experts by text query. * IRegistry interface method. * * Searches expert ID, name, role, and capabilities. * * @param searchTerm - Search term to match * @returns Array of matching experts */ search(searchTerm: string): Expert[]; /** * Get the number of registered experts. */ get size(): number; /** * Check if the registry is empty. */ get isEmpty(): boolean; /** * Clear all registered experts. */ clear(): void; /** * Get statistics about the registry. * Returns IRegistryStats-compatible stats with domain-specific extensions. */ getStats(): RegistryStats; /** * Find the best expert for a set of required capabilities. * * Returns the expert that matches the most capabilities. * * @param requiredCapabilities - Capabilities needed * @returns Result with best Expert or RegistryError if none found */ findBestMatch(requiredCapabilities: AgentCapability[]): Result; } /** * Get the global expert registry instance. */ declare function getExpertRegistry(): ExpertRegistry$1; /** * nexus-agents/agents - Expert Selector Types * * Shared types for expert selection to avoid circular dependencies. * * @module agents/experts/expert-selector-types */ type TaskDomain = ExpertTaskDomain; /** Collaboration patterns for multi-expert tasks. */ declare const ExpertCollaborationPattern: { readonly SEQUENTIAL: "sequential"; readonly PARALLEL: "parallel"; readonly REVIEW_CHAIN: "review_chain"; readonly PAIR: "pair"; }; type ExpertCollaborationPatternType = (typeof ExpertCollaborationPattern)[keyof typeof ExpertCollaborationPattern]; /** * Definition of an expert's capabilities and metadata. */ interface ExpertDefinition { /** Unique expert identifier */ id: string; /** Expert role type */ role: AgentRole; /** Human-readable name */ name: string; /** Description of expert's specialty */ description: string; /** Core capabilities */ capabilities: string[]; /** Primary domain of expertise */ primaryDomain: TaskDomain; /** Additional domains the expert can handle */ secondaryDomains: TaskDomain[]; /** Base weight for scoring (0-1) */ weight: number; /** Whether the expert is currently available */ available: boolean; } /** Registry of available experts. */ interface ExpertRegistry { getAll(): ExpertDefinition[]; getById(id: string): ExpertDefinition | undefined; getByRole(role: AgentRole): ExpertDefinition[]; getByDomain(domain: TaskDomain): ExpertDefinition[]; getAvailable(): ExpertDefinition[]; } /** * Breakdown of how the match score was calculated. */ interface ScoreBreakdown { /** Score from capability matching (0-1) */ capabilityScore: number; /** Score from domain alignment (0-1) */ domainScore: number; /** Score from weight adjustment (0-1) */ weightScore: number; /** Combined final score (0-1) */ finalScore: number; } /** * Match result for a single expert. */ interface ExpertMatch { /** Expert identifier */ expertId: string; /** Match score (0-1) */ score: number; /** Capabilities that matched the task */ matchedCapabilities: string[]; /** Human-readable reasoning for the match */ reasoning: string; /** Breakdown of score components */ scoreBreakdown: ScoreBreakdown; } /** Result of expert selection. */ interface SelectionResult$1 { primary: ExpertMatch; alternatives: ExpertMatch[]; requiresCollaboration: boolean; suggestedPattern?: ExpertCollaborationPatternType; confidence: number; } /** Options for expert selection. */ interface SelectionOptions { minScore?: number; maxAlternatives?: number; capabilityWeights?: Record; preferredDomains?: TaskDomain[]; excludeExperts?: string[]; forceCollaboration?: boolean; } declare const ScoreBreakdownSchema: z.ZodObject<{ capabilityScore: z.ZodNumber; domainScore: z.ZodNumber; weightScore: z.ZodNumber; finalScore: z.ZodNumber; }, z.core.$strip>; declare const ExpertMatchSchema: z.ZodObject<{ expertId: z.ZodString; score: z.ZodNumber; matchedCapabilities: z.ZodArray; reasoning: z.ZodString; scoreBreakdown: z.ZodObject<{ capabilityScore: z.ZodNumber; domainScore: z.ZodNumber; weightScore: z.ZodNumber; finalScore: z.ZodNumber; }, z.core.$strip>; }, z.core.$strip>; declare const SelectionResultSchema: z.ZodObject<{ primary: z.ZodObject<{ expertId: z.ZodString; score: z.ZodNumber; matchedCapabilities: z.ZodArray; reasoning: z.ZodString; scoreBreakdown: z.ZodObject<{ capabilityScore: z.ZodNumber; domainScore: z.ZodNumber; weightScore: z.ZodNumber; finalScore: z.ZodNumber; }, z.core.$strip>; }, z.core.$strip>; alternatives: z.ZodArray; reasoning: z.ZodString; scoreBreakdown: z.ZodObject<{ capabilityScore: z.ZodNumber; domainScore: z.ZodNumber; weightScore: z.ZodNumber; finalScore: z.ZodNumber; }, z.core.$strip>; }, z.core.$strip>>; requiresCollaboration: z.ZodBoolean; suggestedPattern: z.ZodOptional>; confidence: z.ZodNumber; }, z.core.$strip>; declare const SelectionOptionsSchema: z.ZodObject<{ minScore: z.ZodOptional; maxAlternatives: z.ZodOptional; capabilityWeights: z.ZodOptional>; preferredDomains: z.ZodOptional>>; excludeExperts: z.ZodOptional>; forceCollaboration: z.ZodOptional; }, z.core.$strip>; /** * nexus-agents/agents - Expert Selector * * Selects the best experts for a task based on capability matching, * domain alignment, and scoring algorithms. */ /** Error thrown when expert selection fails. */ declare class SelectionError extends NexusError { constructor(message: string, options?: { cause?: Error; context?: Record; }); } /** * Creates a default expert registry with built-in experts. */ declare function createDefaultRegistry(): ExpertRegistry; /** * Selects the best experts for a task. * @param task - The task to select experts for * @param registry - Registry of available experts * @param options - Optional selection configuration */ declare function selectExperts(task: Task$1, registry: ExpertRegistry, options?: SelectionOptions): Result; /** * Quick selection using default registry. * Convenience function for simple use cases. * Uses a cached registry for performance optimization. */ declare function quickSelect(task: Task$1, options?: SelectionOptions): Result; /** * nexus-agents/agents - Aggregator Types * * Types shared between result-aggregator and aggregator-helpers. * Extracted to prevent circular dependencies. */ /** * Aggregation strategy types. */ type AggregationStrategy = 'merge' | 'select_best' | 'consensus' | 'sequential_chain'; /** * Expert result with metadata. */ interface ExpertResult { expertId: string; result: TaskResult; confidence?: number; order?: number; } /** * Conflict resolver function type. */ type ConflictResolver = (conflict: ResultConflict, result1: ExpertResult, result2: ExpertResult) => 'expert1' | 'expert2' | 'merged'; /** * Quality scorer function type. */ type QualityScorer = (results: ExpertResult[], aggregatedOutput: unknown) => number; /** * Input for aggregation. */ interface AggregatorInput { pattern: CollaborationPattern; results: ExpertResult[]; votes?: VoteMessage[]; reviews?: ReviewResponseMessage[]; } /** * nexus-agents/agents - Result Aggregator * * Aggregates results from multiple experts into a final output. * Handles merging, conflict detection, and quality scoring. */ /** * Options for result aggregation. */ interface AggregatorOptions { logger?: ILogger; conflictResolver?: ConflictResolver; qualityScorer?: QualityScorer; minQualityScore?: number; } declare class ResultAggregator { private readonly logger; private readonly conflictResolver; private readonly qualityScorer; private readonly minQualityScore; constructor(options?: AggregatorOptions); /** * Aggregates expert results into a final result. */ aggregate(input: AggregatorInput): Result; /** * `conflictsDetected` travels with the conflict list because only one of * these branches compares anything (#4854). `select_best`, `consensus` and * `sequential_chain` pick or concatenate; an empty list from them is the * absence of a check, not the absence of disagreement. */ private applyStrategy; private checkQuality; private buildResult; /** * Merges multiple results into one. * * Only the object branch performs a comparison — strings are unioned * line-by-line, arrays concatenated, and mixed outputs simply collected * under `sources`. Each branch reports whether it looked (#4854). */ private mergeResults; } /** * Creates a result aggregator. */ declare function createResultAggregator(options?: AggregatorOptions): ResultAggregator; /** * Convenience function to aggregate results. */ declare function aggregateResults(input: AggregatorInput, options?: AggregatorOptions): Result; /** * TRINITY Coordinator Types * * Type definitions for the TRINITY Thinker/Worker/Verifier pattern * from arXiv:2512.04695. Achieves 86.2% accuracy on LiveCodeBench. * * @module agents/collaboration/trinity-types * (Source: Issue #141, arXiv:2512.04695) */ /** TRINITY-specific roles. */ type TrinityRole = 'thinker' | 'worker' | 'verifier'; /** Configuration for a TRINITY role. */ interface TrinityRoleConfig { /** Role identifier */ readonly role: TrinityRole; /** System prompt for this role */ readonly systemPrompt: string; /** Temperature for completions */ readonly temperature: number; /** Maximum tokens for response */ readonly maxTokens: number; } /** Default prompts for each TRINITY role. */ declare const TRINITY_ROLE_PROMPTS: Record; /** Default temperatures for TRINITY roles. */ declare const TRINITY_ROLE_TEMPERATURES: Record; /** Default max tokens for TRINITY roles. */ declare const TRINITY_ROLE_MAX_TOKENS: Record; /** Phase of TRINITY coordination. */ type TrinityPhase = 'thinking' | 'working' | 'verifying' | 'complete'; /** Result from a single TRINITY phase. */ interface TrinityPhaseResult { /** Which phase produced this result */ readonly phase: TrinityPhase; /** Role that executed this phase */ readonly role: TrinityRole; /** Output from the phase */ readonly output: string; /** Duration in milliseconds */ readonly durationMs: number; /** Tokens used. Meaningful only when `tokensMeasured` is not `false`. */ readonly tokensUsed: number; /** * Whether `tokensUsed` is a measurement (#4743). * * `false` means the adapter reported no usage, so `tokensUsed` is a * placeholder zero rather than a count. Absent means the producer predates * the distinction — unknown, not measured. Additive and optional, so no * existing reader breaks. */ readonly tokensMeasured?: boolean; } /** Thinker's analysis output. */ interface ThinkerOutput { /** Problem analysis */ readonly problemAnalysis: string; /** Execution approach/plan */ readonly approach: string; /** Considerations and edge cases */ readonly considerations: string[]; /** Success criteria */ readonly successCriteria: string[]; } /** Worker's implementation output. */ interface WorkerOutput { /** The actual implementation/content */ readonly implementation: string; /** Steps completed */ readonly stepsCompleted: string[]; /** Deviations from plan */ readonly deviations: string[]; /** Questions or blockers */ readonly questions: string[]; } /** Verifier's evaluation output. */ interface VerifierOutput { /** Pass or fail verdict */ readonly verdict: 'pass' | 'fail'; /** Correctness assessment */ readonly correctnessCheck: string; /** Quality assessment */ readonly qualityCheck: string; /** Issues found */ readonly issuesFound: string[]; /** Recommendations */ readonly recommendations: string[]; } /** Configuration for TRINITY coordinator. */ interface TrinityConfig { /** Maximum verification iterations before giving up */ readonly maxIterations?: number; /** Timeout for entire coordination in ms */ readonly timeoutMs?: number; /** Whether to include detailed phase history */ readonly includeHistory?: boolean; /** Custom role configurations */ readonly roleConfigs?: Partial>>; } /** Default TRINITY configuration. */ declare const DEFAULT_TRINITY_CONFIG: Required; /** Result of TRINITY coordination. */ interface TrinityResult { /** Whether coordination succeeded */ readonly success: boolean; /** Final output after all phases */ readonly finalOutput: string; /** Thinker's analysis */ readonly thinkerOutput: ThinkerOutput; /** Worker's implementation */ readonly workerOutput: WorkerOutput; /** Verifier's final assessment */ readonly verifierOutput: VerifierOutput; /** Number of think-work-verify iterations */ readonly iterations: number; /** Total duration in milliseconds */ readonly totalDurationMs: number; /** Phase execution history */ readonly history: TrinityPhaseResult[]; /** Stop reason */ readonly stopReason: 'verified' | 'max_iterations' | 'timeout' | 'error'; } /** Schema for TRINITY role. */ declare const TrinityRoleSchema: z.ZodEnum<{ thinker: "thinker"; worker: "worker"; verifier: "verifier"; }>; /** Schema for TRINITY phase. */ declare const TrinityPhaseSchema: z.ZodEnum<{ thinking: "thinking"; working: "working"; complete: "complete"; verifying: "verifying"; }>; /** Schema for verifier verdict. */ declare const VerifierVerdictSchema: z.ZodEnum<{ pass: "pass"; fail: "fail"; }>; /** Schema for TrinityConfig. */ declare const TrinityConfigSchema: z.ZodObject<{ maxIterations: z.ZodOptional; timeoutMs: z.ZodOptional; includeHistory: z.ZodOptional; roleConfigs: z.ZodOptional, z.ZodObject<{ systemPrompt: z.ZodOptional; temperature: z.ZodOptional; maxTokens: z.ZodOptional; }, z.core.$strip>>>; }, z.core.$strip>; /** Schema for stop reason. */ declare const TrinityStopReasonSchema: z.ZodEnum<{ error: "error"; timeout: "timeout"; max_iterations: "max_iterations"; verified: "verified"; }>; /** Options for executing TRINITY coordination. */ interface TrinityExecuteOptions { readonly task: Task$1; readonly agent: IAgent; } /** Options for TrinityCoordinator constructor. */ interface TrinityCoordinatorOptions { readonly config?: TrinityConfig; /** Optional event bus for protocol lifecycle events. Uses global bus if not provided. */ readonly eventBus?: ICollaborationEventBus; } /** * TRINITY Coordinator * * Implements the TRINITY Thinker/Worker/Verifier pattern from arXiv:2512.04695. * Coordinates three specialized roles for high-quality task execution. * * Flow: Think → Work → Verify → (iterate if failed) → Complete * * @module agents/collaboration/trinity-coordinator * (Source: Issue #141, arXiv:2512.04695) */ /** * Coordinates Thinker, Worker, and Verifier roles for task execution. */ declare class TrinityCoordinator { private readonly config; private readonly trinityConfig; private readonly log; private readonly eventBus; private cancelFlag; constructor(options?: TrinityConfig | TrinityCoordinatorOptions); /** Normalizes constructor options for backward compatibility. */ private normalizeOptions; cancel(reason: string): void; execute(options: TrinityExecuteOptions): Promise>; private runCoordination; private runIterationLoop; /** Emits an iteration event with given status. */ private emitIteration; /** Builds result, emits completed event, and returns. */ private emitAndReturn; /** Shorthand for emitAndReturn with inline arguments. */ private returnResult; private runThinker; private runWorker; private runVerifier; private createPhaseResult; private isTimedOut; private buildCancelledResult; private buildResult; } /** Creates a TRINITY coordinator instance. */ declare function createTrinityCoordinator(config?: TrinityConfig): TrinityCoordinator; /** * nexus-agents/agents - Skill Security Types * * Type definitions, interfaces, and constants for skill security controls. * Implements capability-based permissions, RBAC, provenance tracking, * and execution attestation for safe skill auto-loading. * * @module agents/skills/skill-security-types * (Source: Issue #374, Phase 1) */ /** * Available skill permissions. * Each permission grants specific capabilities to a skill. */ type SkillPermission = 'read' | 'write' | 'execute' | 'network' | 'filesystem' | 'spawn'; /** * All valid skill permissions as a readonly array. */ declare const SKILL_PERMISSIONS: readonly SkillPermission[]; /** * Default permissions for new skills (minimal, read-only). */ declare const DEFAULT_PERMISSIONS: readonly SkillPermission[]; /** * Maximum execution time in milliseconds. */ declare const MAX_EXECUTION_TIME_MS = 300000; /** * Default execution time limit in milliseconds. */ declare const DEFAULT_EXECUTION_TIME_MS = 30000; /** * Skill capabilities define what a skill can do and its execution constraints. */ interface SkillCapabilities { /** Permissions granted to the skill */ readonly permissions: readonly SkillPermission[]; /** Maximum execution time in milliseconds */ readonly maxExecutionTime: number; /** Whether the skill runs in a sandboxed environment */ readonly sandboxed: boolean; } /** * Default capabilities for new skills. */ declare const DEFAULT_CAPABILITIES: SkillCapabilities; /** * Role-based access control for skill execution. */ interface SkillRBAC { /** Roles that are allowed to execute this skill */ readonly allowedRoles: readonly AgentRole[]; /** Roles that are explicitly denied (takes precedence over allowed) */ readonly deniedRoles?: readonly AgentRole[]; /** Whether execution requires attestation even for allowed roles */ readonly requiresAttestation: boolean; } /** * Default RBAC allowing all roles without attestation requirement. */ declare const DEFAULT_RBAC: SkillRBAC; /** * Tracks the origin and modification history of a skill. */ interface SkillProvenance { /** Identifier of who created the skill */ readonly createdBy: string; /** When the skill was created */ readonly createdAt: Date; /** Identifier of who last modified the skill */ readonly modifiedBy?: string; /** When the skill was last modified */ readonly modifiedAt?: Date; /** Version number (increments on modification) */ readonly version: number; /** Cryptographic signature for verification */ readonly signature?: string; } /** * Method used to authorize skill execution. */ type AuthorizationMethod = 'role' | 'explicit' | 'inherited'; /** * Records the authorization of a skill execution. */ interface SkillAttestation { /** ID of the skill being executed */ readonly skillId: string; /** ID of the agent executing the skill */ readonly executorId: string; /** When the attestation was created */ readonly timestamp: Date; /** SHA-256 hash of the input parameters */ readonly inputHash: string; /** Whether execution was authorized */ readonly authorized: boolean; /** How authorization was determined */ readonly authorizationMethod: AuthorizationMethod; } /** * Error codes for security-related failures. */ type SecurityErrorCode = 'PERMISSION_DENIED' | 'ROLE_NOT_ALLOWED' | 'ATTESTATION_REQUIRED' | 'INVALID_PROVENANCE' | 'SIGNATURE_MISMATCH' | 'EXECUTION_TIMEOUT' | 'SANDBOX_VIOLATION'; /** * Security error with code and context. */ interface SkillSecurityError { readonly code: SecurityErrorCode; readonly message: string; readonly context?: Record; } /** * nexus-agents/agents - Skill Security Schemas * * Zod validation schemas for skill security types. * Used for runtime validation at trust boundaries. * * @module agents/skills/skill-security-schemas * (Source: Issue #374, Phase 1) */ /** * Zod schema for SkillPermission. */ declare const SkillPermissionSchema: z.ZodEnum<{ network: "network"; spawn: "spawn"; write: "write"; read: "read"; filesystem: "filesystem"; execute: "execute"; }>; /** * Zod schema for AgentRole (mirrors core/types/agent.ts). */ declare const AgentRoleSchema$2: z.ZodEnum<{ custom: "custom"; orchestrator: "orchestrator"; code_expert: "code_expert"; architecture_expert: "architecture_expert"; security_expert: "security_expert"; documentation_expert: "documentation_expert"; testing_expert: "testing_expert"; infrastructure_expert: "infrastructure_expert"; thinker: "thinker"; worker: "worker"; verifier: "verifier"; }>; /** * Zod schema for SkillCapabilities. */ declare const SkillCapabilitiesSchema: z.ZodObject<{ permissions: z.ZodReadonly>>; maxExecutionTime: z.ZodNumber; sandboxed: z.ZodBoolean; }, z.core.$strip>; /** * Zod schema for SkillRBAC. */ declare const SkillRBACSchema: z.ZodObject<{ allowedRoles: z.ZodReadonly>>; deniedRoles: z.ZodOptional>>>; requiresAttestation: z.ZodBoolean; }, z.core.$strip>; /** * Zod schema for SkillProvenance. */ declare const SkillProvenanceSchema: z.ZodObject<{ createdBy: z.ZodString; createdAt: z.ZodDate; modifiedBy: z.ZodOptional; modifiedAt: z.ZodOptional; version: z.ZodNumber; signature: z.ZodOptional; }, z.core.$strip>; /** * Zod schema for AuthorizationMethod. */ declare const AuthorizationMethodSchema: z.ZodEnum<{ role: "role"; explicit: "explicit"; inherited: "inherited"; }>; /** * Zod schema for SkillAttestation. */ declare const SkillAttestationSchema: z.ZodObject<{ skillId: z.ZodString; executorId: z.ZodString; timestamp: z.ZodDate; inputHash: z.ZodString; authorized: z.ZodBoolean; authorizationMethod: z.ZodEnum<{ role: "role"; explicit: "explicit"; inherited: "inherited"; }>; }, z.core.$strip>; /** * Zod schema for SecurityErrorCode. */ declare const SecurityErrorCodeSchema: z.ZodEnum<{ PERMISSION_DENIED: "PERMISSION_DENIED"; ROLE_NOT_ALLOWED: "ROLE_NOT_ALLOWED"; ATTESTATION_REQUIRED: "ATTESTATION_REQUIRED"; INVALID_PROVENANCE: "INVALID_PROVENANCE"; SIGNATURE_MISMATCH: "SIGNATURE_MISMATCH"; EXECUTION_TIMEOUT: "EXECUTION_TIMEOUT"; SANDBOX_VIOLATION: "SANDBOX_VIOLATION"; }>; /** * Zod schema for SkillSecurityError. */ declare const SkillSecurityErrorSchema: z.ZodObject<{ code: z.ZodEnum<{ PERMISSION_DENIED: "PERMISSION_DENIED"; ROLE_NOT_ALLOWED: "ROLE_NOT_ALLOWED"; ATTESTATION_REQUIRED: "ATTESTATION_REQUIRED"; INVALID_PROVENANCE: "INVALID_PROVENANCE"; SIGNATURE_MISMATCH: "SIGNATURE_MISMATCH"; EXECUTION_TIMEOUT: "EXECUTION_TIMEOUT"; SANDBOX_VIOLATION: "SANDBOX_VIOLATION"; }>; message: z.ZodString; context: z.ZodOptional>; }, z.core.$strip>; /** * nexus-agents/agents - Skill Security Controls * * Security validation functions for the Voyager skill library. * Implements capability-based permissions, RBAC, provenance tracking, * and execution attestation for safe skill auto-loading. * * This module re-exports all types, constants, and schemas from: * - skill-security-types.ts (types, interfaces, constants) * - skill-security-schemas.ts (Zod validation schemas) * * @module agents/skills/skill-security * (Source: Issue #374, Phase 1) */ /** * Checks if an agent role can execute a skill based on RBAC rules. * * @param agentRole - The role of the agent attempting execution * @param rbac - The skill's RBAC configuration * @returns True if the role is allowed to execute the skill */ declare function canExecuteSkill(agentRole: AgentRole, rbac: SkillRBAC): boolean; /** * Creates an attestation record for a skill execution. * * @param skillId - ID of the skill being executed * @param executorId - ID of the agent executing the skill * @param input - Input parameters for the skill * @param authorized - Whether execution is authorized * @param method - How authorization was determined * @returns A new SkillAttestation record */ declare function createAttestation(skillId: string, executorId: string, input: unknown, authorized: boolean, method: AuthorizationMethod): SkillAttestation; /** * Validates skill provenance for integrity. * * @param provenance - The provenance to validate * @returns Result indicating success or validation error */ declare function validateSkillProvenance(provenance: SkillProvenance): Result; /** * Checks if requested permissions are within the skill's permission boundary. * * @param capabilities - The skill's capability configuration * @param requestedPermissions - Permissions being requested for an operation * @returns True if all requested permissions are allowed */ declare function checkPermissionBoundary(capabilities: SkillCapabilities, requestedPermissions: readonly SkillPermission[]): boolean; /** * Creates a security error with the given code and message. * * @param code - The error code * @param message - Human-readable error message * @param context - Additional context for debugging * @returns A SkillSecurityError */ declare function createSecurityError(code: SecurityErrorCode, message: string, context?: Record): SkillSecurityError; /** * Validates capabilities against security constraints. * * @param capabilities - The capabilities to validate * @returns Result indicating success or validation error */ declare function validateCapabilities(capabilities: SkillCapabilities): Result; /** * Validates RBAC configuration. * * @param rbac - The RBAC configuration to validate * @returns Result indicating success or validation error */ declare function validateRBAC(rbac: SkillRBAC): Result; /** * Performs comprehensive security validation for skill execution. * * @param agentRole - The role of the agent attempting execution * @param capabilities - The skill's capabilities * @param rbac - The skill's RBAC configuration * @param requestedPermissions - Permissions needed for the operation * @returns Result indicating success or the first validation error */ declare function validateSkillExecution(agentRole: AgentRole, capabilities: SkillCapabilities, rbac: SkillRBAC, requestedPermissions: readonly SkillPermission[]): Result; /** * nexus-agents/agents - Voyager Skill Library Types * * Types for implementing the Voyager skill library pattern: * an ever-growing library of executable code skills built through * environmental interaction with automatic curriculum learning. * * @module agents/skills/skill-types * (Source: arXiv:2305.16291, Issue #150) */ /** * Skill complexity levels. */ type SkillComplexity = 'primitive' | 'simple' | 'moderate' | 'complex' | 'composite'; /** * Skill execution status. */ type SkillExecutionStatus = 'success' | 'failure' | 'timeout' | 'error'; /** * Skill categories for organization. * * Extended in Epic #643 to support standards absorption categories. */ type SkillCategory = 'file-operations' | 'code-generation' | 'code-analysis' | 'testing' | 'documentation' | 'refactoring' | 'debugging' | 'deployment' | 'general' | 'coding-standards' | 'security' | 'database' | 'cloud-native' | 'devops' | 'api' | 'frontend' | 'observability' | 'compliance'; /** * A single skill in the library. */ interface Skill { /** Unique identifier */ readonly id: string; /** Human-readable name */ readonly name: string; /** Detailed description of what the skill does */ readonly description: string; /** Category for organization */ readonly category: SkillCategory; /** Complexity level */ readonly complexity: SkillComplexity; /** The executable code (function body) */ readonly code: string; /** Input parameter definitions */ readonly parameters: readonly SkillParameter[]; /** Expected output type description */ readonly outputType: string; /** Skills this depends on (for composition) */ readonly dependencies: readonly string[]; /** Keywords for search/retrieval */ readonly tags: readonly string[]; /** Usage example(s) */ readonly examples: readonly SkillExample[]; /** When the skill was created */ readonly createdAt: Date; /** When the skill was last modified */ readonly updatedAt: Date; /** Version number for tracking changes */ readonly version: number; /** Security capabilities (optional, for controlled execution) */ readonly capabilities?: SkillCapabilities; /** Role-based access control (optional, for permission enforcement) */ readonly rbac?: SkillRBAC; /** Provenance tracking (optional, for audit trail) */ readonly provenance?: SkillProvenance; } /** * Parameter definition for a skill. */ interface SkillParameter { /** Parameter name */ readonly name: string; /** Type description */ readonly type: string; /** Parameter description */ readonly description: string; /** Whether the parameter is required */ readonly required: boolean; /** Default value if not required */ readonly defaultValue?: unknown; } /** * Example usage of a skill. */ interface SkillExample { /** Description of what this example demonstrates */ readonly description: string; /** Input values */ readonly input: Record; /** Expected output */ readonly expectedOutput: string; } /** * Record of a skill execution. */ interface SkillExecution { /** ID of the skill executed */ readonly skillId: string; /** When the execution started */ readonly startTime: Date; /** When the execution ended */ readonly endTime: Date; /** Execution status */ readonly status: SkillExecutionStatus; /** Input provided */ readonly input: Record; /** Output produced (if successful) */ readonly output?: string; /** Error message (if failed) */ readonly errorMessage?: string; /** Context in which the skill was used */ readonly context?: string; } /** * Skill performance metrics. */ interface SkillMetrics { /** Total number of executions */ readonly executionCount: number; /** Number of successful executions */ readonly successCount: number; /** Average execution time in milliseconds */ readonly avgExecutionTimeMs: number; /** Success rate (0-1) */ readonly successRate: number; /** Last execution time */ readonly lastExecutedAt?: Date; } /** * A skill with its execution metrics. */ interface SkillWithMetrics extends Skill { /** Execution metrics */ readonly metrics: SkillMetrics; } /** * Query options for skill retrieval. */ interface SkillQuery { /** Search in name and description */ readonly search?: string; /** Filter by category */ readonly category?: SkillCategory; /** Filter by complexity */ readonly complexity?: SkillComplexity; /** Filter by tags (any match) */ readonly tags?: readonly string[]; /** Minimum success rate */ readonly minSuccessRate?: number; /** Maximum number of results */ readonly limit?: number; /** Sort by field */ readonly sortBy?: 'name' | 'successRate' | 'executionCount' | 'createdAt'; /** Sort direction */ readonly sortOrder?: 'asc' | 'desc'; } /** * Result of a skill search. */ interface SkillSearchResult { /** Matching skills with metrics */ readonly skills: readonly SkillWithMetrics[]; /** Total number of matches (before limit) */ readonly totalCount: number; /** Query that produced this result */ readonly query: SkillQuery; } /** * Options for creating a new skill. */ interface CreateSkillOptions { /** Human-readable name */ readonly name: string; /** Detailed description */ readonly description: string; /** Category */ readonly category: SkillCategory; /** Complexity level */ readonly complexity: SkillComplexity; /** The executable code */ readonly code: string; /** Input parameters */ readonly parameters: readonly SkillParameter[]; /** Output type description */ readonly outputType: string; /** Dependencies on other skills */ readonly dependencies?: readonly string[]; /** Search tags */ readonly tags?: readonly string[]; /** Usage examples */ readonly examples?: readonly SkillExample[]; } /** * Skill composition request. */ interface SkillCompositionRequest { /** Task description to solve */ readonly taskDescription: string; /** Available context */ readonly context?: string; /** Preferred complexity limit */ readonly maxComplexity?: SkillComplexity; /** Maximum number of skills to compose */ readonly maxSkillCount?: number; } /** * A composed skill plan. */ interface SkillComposition { /** Skills to execute in order */ readonly steps: readonly CompositionStep[]; /** Overall description */ readonly description: string; /** Estimated complexity */ readonly estimatedComplexity: SkillComplexity; /** Confidence in this composition (0-1) */ readonly confidence: number; } /** * A single step in a skill composition. */ interface CompositionStep { /** Step number (1-indexed) */ readonly stepNumber: number; /** Skill to execute */ readonly skillId: string; /** Skill name (for readability) */ readonly skillName: string; /** How to bind input (from context or previous step) */ readonly inputBinding: Record; /** Description of what this step achieves */ readonly purpose: string; } /** * Input binding for a composition step. */ interface InputBinding { /** Source of the input value */ readonly source: 'context' | 'previous-step' | 'literal'; /** Key in context or step number */ readonly key: string; /** Literal value (if source is 'literal') */ readonly value?: unknown; } /** * Promotion bridge from a per-instance skill library to the shared * memory substrate (Phase 6 of #2792). Called when a skill has * accumulated enough successful executions to be considered reliable. * The implementation typically writes a belief of the form * `subject = "skill:{name}"`, `predicate = "is_reliable_for"`, * `object = "{category}"` so future `getContextForTask` calls surface * the learning across all agents — not just the one that ran it. * * Best-effort: promoter implementations MUST NOT throw out of this * callback. SkillLibrary catches errors defensively, but cleaner not * to throw in the first place. */ interface SkillPromotionEvent { readonly skillId: string; readonly name: string; readonly category: string; readonly successRate: number; readonly executionCount: number; } type SkillPromoter = (event: SkillPromotionEvent) => void | Promise; /** * Configuration for the skill library. */ interface SkillLibraryConfig { /** Maximum skills to store */ readonly maxSkills: number; /** Minimum success rate to keep skill (0-1) */ readonly minSuccessRateForRetention: number; /** Number of executions before evaluating retention */ readonly executionsBeforeEvaluation: number; /** Enable automatic skill pruning */ readonly enablePruning: boolean; /** Whether to track detailed execution history */ readonly trackExecutionHistory: boolean; /** Maximum execution history entries per skill */ readonly maxHistoryPerSkill: number; /** * Minimum successful executions before promoting the skill as a * belief into the shared substrate (Phase 6 of #2792). Default 5. * Skills below this threshold are still tracked locally; promotion * only fires once the signal stabilizes. */ readonly minSuccessesForPromotion: number; /** * Optional promotion bridge to the shared belief store. When set, * SkillLibrary fires the callback whenever a skill crosses the * `minSuccessesForPromotion` threshold. Default: undefined (no-op). */ readonly skillPromoter?: SkillPromoter; } /** * Default skill library configuration. */ declare const DEFAULT_SKILL_LIBRARY_CONFIG: SkillLibraryConfig; /** * Complexity ordering for comparisons. */ declare const COMPLEXITY_ORDER: Record; /** * Library statistics. */ interface LibraryStatistics { readonly totalSkills: number; readonly totalExecutions: number; readonly overallSuccessRate: number; readonly skillsByCategory: Record; readonly skillsByComplexity: Partial>; } /** * In-memory skill storage structure. */ interface SkillStore { skills: Map; executions: Map; metrics: Map; } /** * nexus-agents/agents - Skill Library Helpers * * Helper functions for skill library operations. * * @module agents/skills/skill-helpers * (Source: arXiv:2305.16291, Issue #150) */ /** * Options for recording an execution. */ interface RecordExecutionOptions { readonly skillId: string; readonly status: SkillExecutionStatus; readonly input: Record; readonly output?: string; readonly errorMessage?: string; readonly context?: string; } /** * nexus-agents/agents - Voyager Skill Library * * Implementation of the Voyager skill library pattern: * an ever-growing library of executable code skills with * automatic retrieval, composition, and curriculum learning. * * @module agents/skills/skill-library * (Source: arXiv:2305.16291, Issue #150) */ /** * Voyager-style skill library for storing and retrieving executable skills. */ declare class SkillLibrary { private readonly config; private readonly logger; private readonly store; constructor(config?: Partial, logger?: ILogger); /** * Adds a new skill to the library. */ addSkill(options: CreateSkillOptions): Skill; /** * Retrieves a skill by ID. */ getSkill(skillId: string): SkillWithMetrics | undefined; /** * Retrieves a skill by name. */ getSkillByName(name: string): SkillWithMetrics | undefined; /** * Searches for skills matching a query. */ searchSkills(query: SkillQuery): SkillSearchResult; /** * Records a skill execution (legacy signature). */ recordExecution(skillId: string, status: SkillExecution['status'], input: Record, output?: string, errorMessage?: string): void; /** * Records a skill execution with options object. */ recordExecutionWithOptions(options: RecordExecutionOptions): void; /** Gets all skills in a category. */ getSkillsByCategory(category: string): readonly SkillWithMetrics[]; /** Gets the most successful skills. */ getTopPerformingSkills(limit?: number): readonly SkillWithMetrics[]; /** Gets the most frequently used skills. */ getMostUsedSkills(limit?: number): readonly SkillWithMetrics[]; /** * Finds skills relevant to a task description. */ findRelevantSkills(taskDescription: string, limit?: number): readonly SkillWithMetrics[]; /** * Updates an existing skill. */ updateSkill(skillId: string, updates: Partial): Skill | undefined; /** * Removes a skill from the library. */ removeSkill(skillId: string): boolean; /** Gets library statistics. */ getStatistics(): LibraryStatistics; /** Gets the current configuration. */ getConfig(): SkillLibraryConfig; /** * Stores an execution record. */ private storeExecution; /** * Updates metrics after an execution. */ private updateMetrics; /** * Phase 6 of #2792 — promote a stabilized skill to the shared belief * store so future tasks (executed by other agents) see the signal. * * Fires exactly once per skill, when the successful-execution count * crosses {@link SkillLibraryConfig.minSuccessesForPromotion}. The * `previousMetrics → updatedMetrics` comparison guards against * re-promoting on every subsequent execution. * * Best-effort: a throwing/rejecting promoter is caught here so a * broken promotion bridge never breaks the local skill bookkeeping. */ private maybePromote; /** * Evaluates whether a skill should be retained. */ private evaluateRetention; /** * Removes the lowest performing skill. */ private pruneLowestPerforming; /** * Filters skills by query criteria. */ private filterSkills; /** * Scores skills by relevance to keywords. */ private scoreSkillsByRelevance; } /** * Creates a skill library with optional configuration. */ declare function createSkillLibrary(config?: Partial, logger?: ILogger): SkillLibrary; /** * nexus-agents/agents - Skill Composer * * Composes multiple skills to solve complex tasks. * Part of the Voyager skill library pattern. * * @module agents/skills/skill-composer * (Source: arXiv:2305.16291, Issue #150) */ /** * Configuration for skill composition. */ interface SkillComposerConfig { /** Maximum skills to consider for composition */ readonly maxCandidateSkills: number; /** Maximum steps in a composition */ readonly maxCompositionSteps: number; /** Minimum confidence threshold for compositions */ readonly minConfidence: number; /** Weight for skill success rate in scoring */ readonly successRateWeight: number; /** Weight for complexity match in scoring */ readonly complexityMatchWeight: number; } /** * Default composer configuration. */ declare const DEFAULT_COMPOSER_CONFIG: SkillComposerConfig; /** * Composes skills to solve complex tasks. */ declare class SkillComposer { private readonly config; private readonly logger; private readonly library; constructor(library: SkillLibrary, config?: Partial, logger?: ILogger); /** * Creates a composition plan for a task. */ compose(request: SkillCompositionRequest): SkillComposition | null; /** * Validates that a composition is executable. * * A zero-step composition is reported invalid rather than valid: the step * loop below never runs, so `errors.length === 0` would report "executable" * having checked nothing, and executing it would do nothing (#4585). */ validateComposition(composition: SkillComposition): CompositionValidation; /** * Gets the current configuration. */ getConfig(): SkillComposerConfig; /** * Finds candidate skills for the task. */ private findCandidateSkills; /** * Builds a composition from candidate skills. */ private buildComposition; /** * Extracts keywords from task description. */ private extractTaskKeywords; /** * Scores skills for a specific task. */ private scoreSkillsForTask; /** * Calculates relevance score for a skill. */ private calculateRelevance; /** * Creates composition steps from selected skills. */ private createSteps; /** * Creates input bindings for a step. */ private createInputBindings; /** * Calculates overall confidence for the composition. */ private calculateOverallConfidence; /** * Estimates overall complexity from selected skills. */ private estimateOverallComplexity; /** * Generates a description for the composition. */ private generateCompositionDescription; /** * Validates input bindings for a step. */ private validateBindings; } /** * Result of validating a composition. */ interface CompositionValidation { /** Whether the composition is valid */ readonly valid: boolean; /** Validation errors */ readonly errors: readonly string[]; /** Warnings (not blocking) */ readonly warnings: readonly string[]; } /** * Creates a skill composer. */ declare function createSkillComposer(library: SkillLibrary, config?: Partial, logger?: ILogger): SkillComposer; /** * nexus-agents/agents - Skill Dependency Graph Types * * Type definitions and Zod schemas for skill dependency graph operations. * * @module agents/skills/skill-dependency-graph-types * (Source: arXiv:2512.23880 CASCADE, Issue #374 Phase 2) */ /** * Type of dependency relationship between skills. * - required: Skill cannot execute without dependency * - optional: Skill can execute without, but benefits from dependency * - recommended: Soft dependency, suggestion only */ type SkillDependencyType = 'required' | 'optional' | 'recommended'; /** * Represents a dependency edge between two skills. */ interface SkillDependency { /** ID of the skill that has the dependency */ readonly skillId: string; /** ID of the skill being depended upon */ readonly dependsOn: string; /** Type of dependency relationship */ readonly type: SkillDependencyType; /** Minimum version of the dependency required (optional) */ readonly minVersion?: number; } /** * Error codes for dependency-related failures. */ type DependencyErrorCode = 'CIRCULAR_DEPENDENCY' | 'MISSING_DEPENDENCY' | 'VERSION_MISMATCH' | 'SELF_DEPENDENCY' | 'SKILL_NOT_FOUND'; /** * Dependency error with code and context. */ interface DependencyError { readonly code: DependencyErrorCode; readonly message: string; readonly context?: Record; } /** * Interface for skill dependency graph operations. */ interface ISkillDependencyGraph { /** Adds a skill node to the graph */ addSkill(skillId: string, version?: number): void; /** Adds a dependency edge between skills */ addDependency(dependency: SkillDependency): Result; /** Removes a dependency edge */ removeDependency(skillId: string, dependsOn: string): boolean; /** Gets all dependencies for a skill */ getDependencies(skillId: string): readonly SkillDependency[]; /** Gets all skills that depend on a given skill */ getDependents(skillId: string): readonly string[]; /** Gets execution order using topological sort */ getExecutionOrder(skillIds: readonly string[]): Result; /** Checks if adding a dependency would create a cycle */ hasCircularDependency(skillId: string): boolean; /** Validates the entire graph for consistency */ validateGraph(): Result; /** Gets the number of skills in the graph */ getSkillCount(): number; /** Checks if a skill exists in the graph */ hasSkill(skillId: string): boolean; } /** * Zod schema for SkillDependencyType. */ declare const SkillDependencyTypeSchema: z.ZodEnum<{ optional: "optional"; required: "required"; recommended: "recommended"; }>; /** * Zod schema for SkillDependency. */ declare const SkillDependencySchema: z.ZodObject<{ skillId: z.ZodString; dependsOn: z.ZodString; type: z.ZodEnum<{ optional: "optional"; required: "required"; recommended: "recommended"; }>; minVersion: z.ZodOptional; }, z.core.$strip>; /** * Zod schema for DependencyErrorCode. */ declare const DependencyErrorCodeSchema: z.ZodEnum<{ CIRCULAR_DEPENDENCY: "CIRCULAR_DEPENDENCY"; MISSING_DEPENDENCY: "MISSING_DEPENDENCY"; VERSION_MISMATCH: "VERSION_MISMATCH"; SELF_DEPENDENCY: "SELF_DEPENDENCY"; SKILL_NOT_FOUND: "SKILL_NOT_FOUND"; }>; /** * Zod schema for DependencyError. */ declare const DependencyErrorSchema: z.ZodObject<{ code: z.ZodEnum<{ CIRCULAR_DEPENDENCY: "CIRCULAR_DEPENDENCY"; MISSING_DEPENDENCY: "MISSING_DEPENDENCY"; VERSION_MISMATCH: "VERSION_MISMATCH"; SELF_DEPENDENCY: "SELF_DEPENDENCY"; SKILL_NOT_FOUND: "SKILL_NOT_FOUND"; }>; message: z.ZodString; context: z.ZodOptional>; }, z.core.$strip>; /** * nexus-agents/agents - Skill Dependency Graph Helpers * * Helper functions for skill dependency graph operations. * Extracted to reduce file complexity and improve testability. * * @module agents/skills/skill-dependency-graph-helpers * (Source: arXiv:2512.23880 CASCADE, Issue #374 Phase 2) */ /** * Creates a dependency error with the given code and message. * * @param code - The error code * @param message - Human-readable error message * @param context - Additional context for debugging * @returns A DependencyError */ declare function createDependencyError(code: DependencyErrorCode, message: string, context?: Record): DependencyError; /** * Resolves skill dependencies with fallbacks for missing optional dependencies. * * @param graph - The dependency graph * @param skillIds - Skills to resolve * @param available - Set of available skill IDs * @returns Result with resolved skill IDs or error */ declare function resolveWithFallbacks(graph: ISkillDependencyGraph, skillIds: readonly string[], available: ReadonlySet): Result; /** * Finds missing dependencies for a set of skills. * * @param graph - The dependency graph * @param skillIds - Skills to check * @param available - Set of available skill IDs * @returns Array of missing required dependency IDs */ declare function findMissingDependencies(graph: ISkillDependencyGraph, skillIds: readonly string[], available: ReadonlySet): readonly string[]; /** * nexus-agents/agents - Skill Dependency Graph * * Manages skill dependencies for execution ordering using topological sort. * Implements Kahn's algorithm for execution order and DFS-based cycle detection. * * @module agents/skills/skill-dependency-graph * (Source: arXiv:2512.23880 CASCADE, Issue #374 Phase 2) */ /** * Skill dependency graph implementation using adjacency list. * Supports topological sorting, cycle detection, and version constraints. */ declare class SkillDependencyGraph implements ISkillDependencyGraph { /** Adjacency list representation */ private readonly nodes; /** Node lookup function for cycle detection utilities */ private readonly nodeLookup; /** Adds a skill node to the graph. */ addSkill(skillId: string, version?: number): void; /** Adds a dependency edge between two skills. */ addDependency(dependency: SkillDependency): Result; /** Removes a dependency edge between two skills. */ removeDependency(skillId: string, dependsOn: string): boolean; /** Gets all dependencies for a skill. */ getDependencies(skillId: string): readonly SkillDependency[]; /** Gets all skills that depend on a given skill. */ getDependents(skillId: string): readonly string[]; /** Gets execution order for given skills using Kahn's algorithm. */ getExecutionOrder(skillIds: readonly string[]): Result; /** Checks if a skill has a circular dependency. */ hasCircularDependency(skillId: string): boolean; /** Validates the entire graph for consistency. */ validateGraph(): Result; /** Gets the number of skills in the graph. */ getSkillCount(): number; /** Checks if a skill exists in the graph. */ hasSkill(skillId: string): boolean; private checkVersionConstraint; private collectRelevantSkills; private topologicalSort; } /** Builds a dependency graph from an array of skills. */ declare function buildDependencyGraph$1(skills: readonly Skill[]): ISkillDependencyGraph; /** Creates an empty skill dependency graph. */ declare function createSkillDependencyGraph(): ISkillDependencyGraph; /** * Maps an agent role to its required and optional skill categories. * Defines which skills should be loaded for agents of a specific role. */ interface RoleSkillMapping { /** The agent role this mapping applies to */ readonly role: AgentRole; /** Categories that must be loaded for this role */ readonly requiredCategories: readonly SkillCategory[]; /** Categories that may be loaded if available */ readonly optionalCategories?: readonly SkillCategory[]; /** Maximum number of skills to load for this role (overrides default) */ readonly maxSkills?: number; } /** * Configuration for fallback behavior when skills cannot be loaded. * - error: Fail the load operation with an error * - partial: Load whatever skills are available * - empty: Return an empty skill set */ type FallbackBehavior = 'error' | 'partial' | 'empty'; /** * Configuration for the skill loader. */ interface SkillLoaderConfig { /** Role-to-skill category mappings */ readonly mappings: readonly RoleSkillMapping[]; /** Default maximum skills per agent if not specified in mapping */ readonly defaultMaxSkills: number; /** Whether to enforce RBAC checks during loading */ readonly enforceRBAC: boolean; /** Whether to enforce dependency ordering */ readonly enforceDependencies: boolean; /** Behavior when required skills are missing */ readonly fallbackBehavior: FallbackBehavior; } /** * Represents a loaded set of skills for an agent. * Includes execution order based on dependencies. */ interface LoadedSkillSet { /** ID of the agent this skill set was loaded for */ readonly agentId: string; /** Role of the agent */ readonly agentRole: AgentRole; /** Skills that were successfully loaded */ readonly skills: readonly Skill[]; /** Execution order (skill IDs) based on dependency graph */ readonly executionOrder: readonly string[]; /** Required skills that could not be loaded */ readonly missingRequired: readonly string[]; /** When the skill set was loaded */ readonly loadedAt: Date; } /** * Error codes for skill loader failures. */ type SkillLoaderErrorCode = 'ROLE_NOT_MAPPED' | 'REQUIRED_CATEGORY_MISSING' | 'RBAC_DENIED' | 'DEPENDENCY_ERROR' | 'VALIDATION_ERROR' | 'EMPTY_RESULT'; /** * Skill loader error with code and context. */ interface SkillLoaderError { readonly code: SkillLoaderErrorCode; readonly message: string; readonly context?: Record; } /** * Interface for the skill loader. */ interface ISkillLoader { /** * Loads skills for an agent based on their role. * Returns skills in dependency-aware execution order. * * @param agentId - Unique identifier of the agent * @param role - Role of the agent * @returns Result with LoadedSkillSet or SkillLoaderError */ loadForAgent(agentId: string, role: AgentRole): Result; /** * Loads skills for a specific task based on role and task description. * May include additional task-relevant skills beyond role defaults. * * @param agentId - Unique identifier of the agent * @param role - Role of the agent * @param taskDescription - Description of the task to execute * @returns Result with LoadedSkillSet or SkillLoaderError */ loadForTask(agentId: string, role: AgentRole, taskDescription: string): Result; /** * Gets all skills available to a specific role. * Does not apply per-agent limits or task filtering. * * @param role - Role to get available skills for * @returns Array of skills available to the role */ getAvailableSkills(role: AgentRole): readonly Skill[]; /** * Validates a loaded skill set for consistency. * * @param set - The loaded skill set to validate * @returns Result with void on success or SkillLoaderError on failure */ validateLoadedSet(set: LoadedSkillSet): Result; } /** * Zod schema for SkillLoaderConfig. */ declare const SkillLoaderConfigSchema: z.ZodObject<{ mappings: z.ZodReadonly; requiredCategories: z.ZodReadonly>>; optionalCategories: z.ZodOptional>>>; maxSkills: z.ZodOptional; }, z.core.$strip>>>; defaultMaxSkills: z.ZodDefault; enforceRBAC: z.ZodDefault; enforceDependencies: z.ZodDefault; fallbackBehavior: z.ZodDefault>; }, z.core.$strip>; /** * Zod schema for LoadedSkillSet. */ declare const LoadedSkillSetSchema: z.ZodObject<{ agentId: z.ZodString; agentRole: z.ZodEnum<{ custom: "custom"; orchestrator: "orchestrator"; code_expert: "code_expert"; architecture_expert: "architecture_expert"; security_expert: "security_expert"; documentation_expert: "documentation_expert"; testing_expert: "testing_expert"; devops_expert: "devops_expert"; thinker: "thinker"; worker: "worker"; verifier: "verifier"; }>; skills: z.ZodReadonly>; executionOrder: z.ZodReadonly>; missingRequired: z.ZodReadonly>; loadedAt: z.ZodDate; }, z.core.$strip>; /** * Zod schema for SkillLoaderError. */ declare const SkillLoaderErrorSchema: z.ZodObject<{ code: z.ZodEnum<{ VALIDATION_ERROR: "VALIDATION_ERROR"; ROLE_NOT_MAPPED: "ROLE_NOT_MAPPED"; REQUIRED_CATEGORY_MISSING: "REQUIRED_CATEGORY_MISSING"; RBAC_DENIED: "RBAC_DENIED"; DEPENDENCY_ERROR: "DEPENDENCY_ERROR"; EMPTY_RESULT: "EMPTY_RESULT"; }>; message: z.ZodString; context: z.ZodOptional>; }, z.core.$strip>; /** * Default role-to-skill category mappings. * Maps expert roles to their appropriate skill categories. */ declare const DEFAULT_ROLE_MAPPINGS: readonly RoleSkillMapping[]; /** * Default skill loader configuration. */ declare const DEFAULT_SKILL_LOADER_CONFIG: SkillLoaderConfig; /** * nexus-agents/agents - Skill Loader Integration Hooks * * Integration functions for connecting the skill loader with the agent system. * These hooks provide convenient wrappers for common skill loading operations * during agent initialization and task execution. * * @module agents/skills/skill-loader-integration * (Source: Issue #374 Phase 3) */ /** * Initializes skills for an agent during agent setup. * * Loads the appropriate skills for the agent's role and validates * the loaded skill set for consistency. This should be called during * agent initialization to ensure skills are ready for task execution. * * @param agent - The agent to initialize skills for * @param loader - The skill loader to use * @returns Result with void on success or SkillLoaderError on failure * * @example * ```typescript * const agent = createAgent({ id: 'agent-1', role: 'code_expert' }); * const loader = createSkillLoader(library); * * const result = initializeAgentSkills(agent, loader); * if (!result.ok) { * console.error('Failed to initialize skills:', result.error); * } * ``` */ declare function initializeAgentSkills(agent: IAgent, loader: ISkillLoader): Result; /** * Gets skills appropriate for a task execution. * * Loads skills based on the agent's role and the task description, * potentially including additional task-relevant skills beyond * the agent's default role-based skills. * * @param agent - The agent that will execute the task * @param task - The task to get skills for * @param loader - The skill loader to use * @returns Result with readonly array of skills or SkillLoaderError on failure * * @example * ```typescript * const agent = createAgent({ id: 'agent-1', role: 'code_expert' }); * const task = { id: 'task-1', description: 'Refactor the user service' }; * const loader = createSkillLoader(library); * * const result = getSkillsForTask(agent, task, loader); * if (result.ok) { * console.log(`Loaded ${result.value.length} skills for task`); * } * ``` */ declare function getSkillsForTask(agent: IAgent, task: Task$1, loader: ISkillLoader): Result; /** * Gets the full loaded skill set for a task execution. * * Unlike `getSkillsForTask`, this returns the complete `LoadedSkillSet` * including execution order and missing required information. * * @param agent - The agent that will execute the task * @param task - The task to get skills for * @param loader - The skill loader to use * @returns Result with LoadedSkillSet or SkillLoaderError on failure */ declare function getSkillSetForTask(agent: IAgent, task: Task$1, loader: ISkillLoader): Result; /** * nexus-agents/agents - Deterministic Skill Loader * * Implements the skill loader for role-based skill assignment. * Provides deterministic loading: same role + same library = same skills. * Uses SkillLibrary for retrieval, SkillDependencyGraph for ordering, * and skill-security for RBAC enforcement. * * @module agents/skills/skill-loader * (Source: Issue #374 Phase 3) */ /** * Deterministic skill loader implementation. * * Key guarantees: * - Same role + same library state = same skill set (deterministic) * - Skills are sorted by ID before filtering for determinism * - Execution order follows dependency graph (topological sort) * - RBAC enforcement prevents unauthorized skill access */ declare class SkillLoader implements ISkillLoader { private readonly config; private readonly library; private readonly logger; private readonly mappingIndex; constructor(library: SkillLibrary, config?: Partial, logger?: ILogger); /** * Loads skills for an agent based on their role. * Deterministic: same role + same library = same skills. */ loadForAgent(agentId: string, role: AgentRole): Result; /** * Collects skills for a mapping and applies RBAC filtering. */ private collectAndFilterSkills; /** * Validates missing categories and returns error if fallback is 'error'. */ private validateMissingCategories; /** * Validates that skills are non-empty and returns error if fallback is 'error'. */ private validateNonEmpty; /** * Gets execution order or falls back to ID order on error. */ private getExecutionOrderOrFallback; /** * Builds the LoadedSkillSet result object. */ private buildLoadedSkillSet; /** * Loads skills for a task, potentially including task-relevant skills. */ loadForTask(agentId: string, role: AgentRole, taskDescription: string): Result; /** * Gets all skills available to a role without limits. */ getAvailableSkills(role: AgentRole): readonly Skill[]; /** * Validates a loaded skill set for consistency. */ validateLoadedSet(set: LoadedSkillSet): Result; private handleUnmappedRole; private checkRequiredCategories; private computeSkillOrder; } /** * Creates a skill loader with the given library and configuration. */ declare function createSkillLoader(library: SkillLibrary, config?: Partial, logger?: ILogger): ISkillLoader; /** * Public type contracts for the agentic-adapter primitive (#2529). * * `IAgenticAdapter` is the multi-turn tool-use counterpart to * `IModelAdapter`'s single-shot `complete()`. Eval harnesses (and any * other consumer that needs an agent loop) drive their own toolset * and tool execution; the adapter handles model orchestration. * * @module agents/agentic/types */ /** * Tool call emitted by the model. * * Mirrors the Anthropic Messages API `tool_use` ContentBlock shape; * the wrapper translates whatever the underlying provider produces * into this canonical form so harnesses don't care which provider * they're talking to. */ interface ToolCall { /** Unique id for this tool call, threaded back through `tool_use_id`. */ readonly id: string; /** Tool name (must match a `ToolDefinition.name` from the input). */ readonly name: string; /** Arguments — already JSON-parsed; provider-side is responsible for parsing. */ readonly arguments: Record; } /** * Result of a tool call, returned by the harness's `onToolCall`. * * `content` is whatever string representation of the result the model * should see next turn. Convention: stringify objects, prefer one-line * for primitives. `isError` tells the model the call failed (Anthropic * surfaces this as `is_error: true` in the next turn's `tool_result` * block; other providers handle similarly). */ interface ToolResult { readonly content: string; readonly isError?: boolean; } /** * One turn of the agent loop — model emits a tool call, harness * resolves it, harness records the trace. */ interface AgentTurn { readonly turnIndex: number; readonly toolCall: ToolCall; readonly toolResult: ToolResult; /** Wall-clock time spent in the model API call that produced the tool call. */ readonly modelLatencyMs: number; /** Wall-clock time spent waiting for `onToolCall` to resolve. */ readonly toolLatencyMs: number; /** Provider-reported input tokens for this turn's API call (when available). */ readonly inputTokens?: number; /** Provider-reported output tokens for this turn's API call (when available). */ readonly outputTokens?: number; } /** * Why the agent loop stopped. * * - `agent-stopped`: model emitted no further tool calls — natural end * - `turn-budget`: hit `turnBudget` before the model finished * - `tool-error`: `onToolCall` threw; harness's responsibility to grade * - `cancelled`: external `AbortSignal` fired */ type AgentStopReason = 'agent-stopped' | 'turn-budget' | 'tool-error' | 'cancelled'; /** * Final result of a successful `runAgent` call. * * `stopReason: 'agent-stopped' | 'turn-budget' | 'tool-error' | 'cancelled'` * is reported via the result, NOT via `Result.err` — partial-progress * runs are gradable, and the harness inspects `turns` to decide. */ interface AgentRunResult { readonly turnsUsed: number; readonly stopReason: AgentStopReason; readonly turns: readonly AgentTurn[]; /** Aggregated token usage across all turns (sum of per-turn inputs/outputs). */ readonly totalInputTokens?: number; readonly totalOutputTokens?: number; /** * Provider-id stamp from the underlying `IModelAdapter` — operators * read this when comparing eval results across providers, since * tool-use fidelity is provider-dependent. */ readonly providerId: string; /** Model-id stamp from the underlying `IModelAdapter`. */ readonly modelId: string; /** * Strategy used to drive the loop. `native:` when the * underlying adapter is a known provider whose tool-use API is being * threaded through; `wrapper` for unknown providers / custom adapters * where the loop relies only on the IModelAdapter contract surface. * * Eval harnesses record this so cross-provider runs are auditable. */ readonly adapterStrategy: string; /** * The model's final assistant content (the response after the last * tool result, when the model emits no further tool call). Empty * string when the loop ended on `turn-budget` or `cancelled`. */ readonly finalContent: string; } /** * Adapter-level errors that can't be recovered into a partial-progress * run. Tool errors and turn-budget are NOT here — they go to * `AgentRunResult.stopReason`. */ declare class AgentError extends Error { readonly causeData?: unknown; constructor(message: string, cause?: unknown); } /** * Arguments to `runAgent`. * * `onToolCall` is the harness's tool-router; the adapter awaits its * `Promise` so synchronous and async harness execution * both work. Per-tool timeouts are the harness's responsibility (the * adapter doesn't impose one — see #2529 design notes). * * `onTurn` (optional) fires once after each turn completes, giving * operators incremental progress visibility. * * `signal` (optional) propagates external cancellation as * `stopReason: 'cancelled'`. */ interface RunAgentArgs { readonly systemPrompt: string; readonly userPrompt: string; readonly tools: readonly ToolDefinition[]; /** * Maximum agent turns. When omitted, the adapter uses the resolved * model's `profile.maxRecommendedTurnBudget` (claude-opus = 20, * o-reasoning = 25, claude-haiku / gemini-flash = 8, defaults to 10). */ readonly turnBudget?: number; readonly onToolCall: (call: ToolCall) => Promise; readonly onTurn?: (turn: AgentTurn) => void; readonly signal?: AbortSignal; /** Sampling temperature passed through to `IModelAdapter.complete`. */ readonly temperature?: number; /** Per-turn maxTokens passed through to `IModelAdapter.complete`. */ readonly maxTokens?: number; } /** * The agentic-adapter contract. Single method; all the variability * lives in `RunAgentArgs`. */ interface IAgenticAdapter { readonly providerId: string; readonly modelId: string; readonly adapterStrategy: string; runAgent(args: RunAgentArgs): Promise>; } /** * `AgenticAdapter` — multi-turn tool-use loop over any `IModelAdapter`. * * Rides on the existing `IModelAdapter.complete` contract: * - request includes `tools: ToolDefinition[]` * - response includes `content: ContentBlock[]` with `tool_use` blocks * - `stopReason: 'tool_use'` signals "the model wants to call tools" * * Each concrete `IModelAdapter` (claude / openai / gemini / opencode / * openrouter / ...) is responsible for translating these into the * provider-native tool-use API. This adapter is provider-agnostic — * one implementation drives all of them. * * Provider-specialised adapters can land later if real fidelity gaps * surface (PR 2 in the #2529 plan); for v1 the wrapper-only path * exercises the contract end-to-end. * * Concurrency: a single `AgenticAdapter` instance is safe for * concurrent `runAgent()` calls. An optional `maxConcurrent` cap * gates the model API call (not the full loop — released during * tool execution), so harnesses running 100s of instances with a * rate-limited provider can throttle without serialising. * * @module agents/agentic/agentic-adapter */ interface AgenticAdapterOptions { /** * Maximum number of concurrent model API calls across all in-flight * `runAgent()` calls. Default unlimited. Set this when the upstream * provider rate-limits aggressively. */ readonly maxConcurrent?: number; /** * Per-model identity overrides — gateway-renamed models, custom * deployments, or anything the modelId-string parser can't classify. * Each field is optional; provided fields force, others fall through * to probe / parse. */ readonly modelHints?: ModelHints; /** * Skip the `IModelAdapter.listModels()` probe at first `runAgent`. * Useful when the gateway doesn't expose `/v1/models` or when * deterministic startup matters more than identity fidelity. */ readonly skipProbe?: boolean; /** * Force a specific behaviour profile, bypassing identity-driven * lookup entirely. Reserved for tests + diagnostic runs; in * production prefer `modelHints` so identity stays auditable. */ readonly forceProfile?: ModelEntry; /** * Override the registry used for `getEntry` lookups. Defaults to * the lazy global registry. Tests and multi-tenant deployments * inject their own. */ readonly registry?: ModelRegistry; } declare class AgenticAdapter implements IAgenticAdapter { readonly providerId: string; readonly modelId: string; /** * Adapter strategy stamp — composed from the resolved model * identity, NOT the IModelAdapter's providerId. For a custom OpenAI * gateway fronting Claude, this reads `native:anthropic` even though * `IModelAdapter.providerId === 'openai'`. * * Initialised eagerly from the modelId parse (sync); upgraded after * the first `runAgent` if the probe contributes a higher-confidence * vendor signal. */ adapterStrategy: string; private readonly model; private readonly options; private readonly registry; private readonly semaphore; private resolvedIdentity; private profile; private profileResolutionPromise; constructor(modelAdapter: IModelAdapter, options?: AgenticAdapterOptions); /** * Read-only accessor for the resolved profile. Mostly used in tests * + observability surfaces; production callers shouldn't need this. */ getProfile(): ModelEntry; /** * Read-only accessor for the resolved identity. After the first * `runAgent` call (if a probe ran), this may differ from what the * sync constructor stored — useful for audit logs. */ getResolvedIdentity(): ResolvedModelIdentity; /** * Lazily resolve identity via the async probe + refresh the profile. * Idempotent + concurrent-call-safe (multiple `runAgent`s share the * same in-flight resolution). */ private ensureIdentityResolved; /** * If the resolved profile asks for `'ephemeral'` prompt caching, * mark the LAST tool definition with `cache_control: { type: * 'ephemeral' }`. Anthropic interprets this as "cache everything up * to and including the tool definitions"; other providers strip the * unknown field at the canonical-request mapper. * * Last-tool placement is the Anthropic convention: cache key is the * prefix, so caching the final tool block caches the entire tools * section. Per-turn the system prompt + user prompt + tools are * stable, so cache-hit rate on multi-turn agent runs is high. */ private applyCacheControlIfRequested; private doResolveIdentity; runAgent(args: RunAgentArgs): Promise>; /** * Run one model-call cycle: call → check for tool_use → execute tool * calls → append results. Returns one of three outcomes describing * whether the loop continues, stops naturally, or hit a model error. */ private runOneTurn; private processToolCalls; private processToolCallsSequential; /** * Profile-driven parallel tool execution. Used when * `profile.parallelToolCalls === true` AND the model emitted >1 * tool_use block in a single turn. * * Each tool call still produces its own `AgentTurn`; turn-budget * applies to the post-completion count (we don't pre-cap the * Promise.all because the model already issued all calls — better * to record everything and let the next turn be the budget breaker). */ private processToolCallsParallel; /** * Records one settled parallel-tool outcome into history. Mutates * `state.turns` / `toolResultBlocks` in place and returns `true` when * the outcome signals a tool error (the caller stops *after* draining * every outcome — #2864). Extracted from `processToolCallsParallel` * to keep that method's cyclomatic complexity under the gate. */ private drainParallelOutcome; /** * Per-call wrapper used by parallel execution. Returns a captured * outcome (turn + result-block, OR turn + tool-error flag) without * touching shared state — `processToolCallsParallel` reduces the * outcomes deterministically afterwards. */ private invokeToolForParallel; private invokeToolAndRecord; private buildFromState; /** * Wrap `model.complete` in an optional concurrency gate. The * semaphore is held only across the model API call — released * before tool execution so harnesses doing slow tool calls don't * starve other concurrent `runAgent` calls. */ private callModelGated; private buildResult; } /** * Factory for `IAgenticAdapter`. * * v1 returns a single concrete `AgenticAdapter` for any * `IModelAdapter` — the underlying model adapter handles * provider-specific tool-use translation already. Provider-specialised * concretes (`AnthropicAgenticAdapter`, etc.) can register here later * if real fidelity gaps surface; consumers call this factory and * never know the difference. * * @module agents/agentic/factory */ /** * Build an `IAgenticAdapter` for the supplied model adapter. * * Stamps `adapterStrategy` based on the model's `providerId` so * downstream eval results record which path they exercised. Future * provider-specialised concretes will set their own strategy. */ declare function createAgenticAdapter(modelAdapter: IModelAdapter, options?: AgenticAdapterOptions): IAgenticAdapter; /** * nexus-agents/agents - Forest-of-Thought Node Types * * Type definitions for reasoning nodes in Forest-of-Thought multi-tree * reasoning with sparse activation. * * @module agents/reasoning/forest-node-types * (Source: arXiv:2412.09078, Issue #331) */ /** * Unique identifier for a reasoning node. */ type NodeId = string; /** * Unique identifier for a reasoning tree. */ type TreeId = string; /** * Unique identifier for a forest (collection of trees). */ type ForestId = string; /** * State of a reasoning node in its lifecycle. * * - `pending`: Node created but not yet processed * - `active`: Node currently being explored/evaluated * - `completed`: Node exploration finished successfully * - `pruned`: Node was pruned due to low score or depth limit * - `error`: Node exploration failed with an error */ type NodeState = 'pending' | 'active' | 'completed' | 'pruned' | 'error'; /** * Schema for NodeState validation. */ declare const NodeStateSchema: z.ZodEnum<{ error: "error"; completed: "completed"; pending: "pending"; pruned: "pruned"; active: "active"; }>; /** * Type of reasoning step represented by a node. * * - `hypothesis`: Initial hypothesis or assumption * - `inference`: Logical deduction from parent node(s) * - `decomposition`: Breaking down a complex problem * - `synthesis`: Combining multiple reasoning paths * - `verification`: Validating a previous step * - `conclusion`: Final answer or decision */ type ReasoningStepType = 'hypothesis' | 'inference' | 'decomposition' | 'synthesis' | 'verification' | 'conclusion'; /** * Schema for ReasoningStepType validation. */ declare const ReasoningStepTypeSchema: z.ZodEnum<{ inference: "inference"; hypothesis: "hypothesis"; synthesis: "synthesis"; decomposition: "decomposition"; verification: "verification"; conclusion: "conclusion"; }>; /** * Metadata associated with a reasoning node. */ interface ReasoningNodeMetadata { /** Source of this reasoning (model, tool, etc.) */ readonly source?: string; /** Tokens used to generate this node */ readonly tokensUsed?: number; /** Time taken to generate this node in ms */ readonly generationTimeMs?: number; /** References to other nodes that informed this reasoning */ readonly crossReferences?: readonly NodeId[]; /** Custom key-value pairs for extensibility */ readonly custom?: Record; } /** * Schema for ReasoningNodeMetadata validation. */ declare const ReasoningNodeMetadataSchema: z.ZodObject<{ source: z.ZodOptional; tokensUsed: z.ZodOptional; generationTimeMs: z.ZodOptional; crossReferences: z.ZodOptional>; custom: z.ZodOptional>; }, z.core.$strip>; /** * A single reasoning step in a reasoning tree. * Represents an atomic unit of thought with content, scoring, and metadata. */ interface ReasoningNode { /** Unique node identifier */ readonly id: NodeId; /** ID of the tree this node belongs to */ readonly treeId: TreeId; /** Parent node ID (null for root nodes) */ readonly parentId: NodeId | null; /** Child node IDs */ readonly children: readonly NodeId[]; /** Depth in the tree (0 for root) */ readonly depth: number; /** Type of reasoning step */ readonly stepType: ReasoningStepType; /** The reasoning content/thought at this step */ readonly content: string; /** Optional structured data associated with this step */ readonly metadata: ReasoningNodeMetadata; /** Current state of this node */ readonly state: NodeState; /** Whether this node is currently activated (for sparse activation) */ readonly isActive: boolean; /** Activation score determining priority (higher = more likely to activate) */ readonly activationScore: number; /** Confidence in this reasoning step (0-1) */ readonly confidence: number; /** Quality score from evaluation (0-1) */ readonly qualityScore: number; /** Estimated value for path selection (like MCTS value) */ readonly estimatedValue: number; /** Creation timestamp */ readonly createdAt: number; /** Last update timestamp */ readonly updatedAt: number; } /** * Schema for ReasoningNode validation. */ declare const ReasoningNodeSchema: z.ZodObject<{ id: z.ZodString; treeId: z.ZodString; parentId: z.ZodNullable; children: z.ZodArray; depth: z.ZodNumber; stepType: z.ZodEnum<{ inference: "inference"; hypothesis: "hypothesis"; synthesis: "synthesis"; decomposition: "decomposition"; verification: "verification"; conclusion: "conclusion"; }>; content: z.ZodString; metadata: z.ZodObject<{ source: z.ZodOptional; tokensUsed: z.ZodOptional; generationTimeMs: z.ZodOptional; crossReferences: z.ZodOptional>; custom: z.ZodOptional>; }, z.core.$strip>; state: z.ZodEnum<{ error: "error"; completed: "completed"; pending: "pending"; pruned: "pruned"; active: "active"; }>; isActive: z.ZodBoolean; activationScore: z.ZodNumber; confidence: z.ZodNumber; qualityScore: z.ZodNumber; estimatedValue: z.ZodNumber; createdAt: z.ZodNumber; updatedAt: z.ZodNumber; }, z.core.$strip>; /** * Input for creating a new reasoning node. */ interface CreateNodeInput { /** Parent node ID (null for root) */ readonly parentId: NodeId | null; /** Tree ID this node belongs to */ readonly treeId: TreeId; /** Type of reasoning step */ readonly stepType: ReasoningStepType; /** Content of the reasoning step */ readonly content: string; /** Initial confidence (0-1) */ readonly confidence: number; /** Optional metadata */ readonly metadata?: Partial; } /** * nexus-agents/agents - Forest-of-Thought Tree Types * * Type definitions for reasoning trees and paths in Forest-of-Thought * multi-tree reasoning with sparse activation. * * @module agents/reasoning/forest-tree-types * (Source: arXiv:2412.09078, Issue #331) */ /** * State of a reasoning tree. * * - `growing`: Tree is actively being explored * - `paused`: Tree exploration temporarily paused * - `completed`: Tree has reached conclusion(s) * - `abandoned`: Tree was abandoned (low quality or pruned) */ type TreeState = 'growing' | 'paused' | 'completed' | 'abandoned'; /** * Schema for TreeState validation. */ declare const TreeStateSchema: z.ZodEnum<{ completed: "completed"; paused: "paused"; growing: "growing"; abandoned: "abandoned"; }>; /** * Scoring breakdown for a reasoning path. */ interface PathScoreBreakdown { /** Average confidence across path nodes */ readonly confidenceScore: number; /** Average quality across path nodes */ readonly qualityScore: number; /** Coherence score (logical consistency between steps) */ readonly coherenceScore: number; /** Depth penalty or bonus based on path length */ readonly depthFactor: number; /** Bonus for reaching conclusion */ readonly conclusionBonus: number; } /** * Schema for PathScoreBreakdown validation. */ declare const PathScoreBreakdownSchema: z.ZodObject<{ confidenceScore: z.ZodNumber; qualityScore: z.ZodNumber; coherenceScore: z.ZodNumber; depthFactor: z.ZodNumber; conclusionBonus: z.ZodNumber; }, z.core.$strip>; /** * A scored path through a reasoning tree from root to a target node. */ interface PathScore { /** Tree this path belongs to */ readonly treeId: TreeId; /** Ordered node IDs from root to target */ readonly path: readonly NodeId[]; /** Target node (usually a conclusion) */ readonly targetNodeId: NodeId; /** Overall path score (0-1) */ readonly score: number; /** Detailed score breakdown */ readonly breakdown: PathScoreBreakdown; /** Whether this path reaches a conclusion */ readonly reachesConclusion: boolean; /** Path length (number of nodes) */ readonly length: number; } /** * Schema for PathScore validation. */ declare const PathScoreSchema: z.ZodObject<{ treeId: z.ZodString; path: z.ZodArray; targetNodeId: z.ZodString; score: z.ZodNumber; breakdown: z.ZodObject<{ confidenceScore: z.ZodNumber; qualityScore: z.ZodNumber; coherenceScore: z.ZodNumber; depthFactor: z.ZodNumber; conclusionBonus: z.ZodNumber; }, z.core.$strip>; reachesConclusion: z.ZodBoolean; length: z.ZodNumber; }, z.core.$strip>; /** * Options for scoring a path. */ interface PathScoringOptions { /** Weight for confidence in scoring */ readonly confidenceWeight: number; /** Weight for quality in scoring */ readonly qualityWeight: number; /** Weight for coherence in scoring */ readonly coherenceWeight: number; /** Penalty per depth level */ readonly depthPenalty: number; /** Bonus for reaching conclusion */ readonly conclusionBonus: number; } /** * Default path scoring options. */ declare const DEFAULT_PATH_SCORING_OPTIONS: PathScoringOptions; /** * Statistics for a reasoning tree. */ interface TreeStatistics { /** Total number of nodes in the tree */ readonly totalNodes: number; /** Number of currently active nodes */ readonly activeNodes: number; /** Maximum depth reached */ readonly maxDepth: number; /** Average node quality score */ readonly avgQualityScore: number; /** Average node confidence */ readonly avgConfidence: number; /** Number of conclusion nodes */ readonly conclusionCount: number; /** Total tokens used across all nodes */ readonly totalTokensUsed: number; /** Average branching factor */ readonly avgBranchingFactor: number; } /** * Schema for TreeStatistics validation. */ declare const TreeStatisticsSchema: z.ZodObject<{ totalNodes: z.ZodNumber; activeNodes: z.ZodNumber; maxDepth: z.ZodNumber; avgQualityScore: z.ZodNumber; avgConfidence: z.ZodNumber; conclusionCount: z.ZodNumber; totalTokensUsed: z.ZodNumber; avgBranchingFactor: z.ZodNumber; }, z.core.$strip>; /** * A reasoning tree containing nodes organized hierarchically. * Each tree explores one approach to solving the problem. */ interface ReasoningTree { /** Unique tree identifier */ readonly id: TreeId; /** ID of the forest this tree belongs to */ readonly forestId: ForestId; /** Root node ID */ readonly rootId: NodeId; /** All nodes in this tree (id -> node) */ readonly nodes: ReadonlyMap; /** Current state of the tree */ readonly state: TreeState; /** Overall tree score for ranking (0-1) */ readonly overallScore: number; /** Priority for exploration (higher = explore first) */ readonly explorationPriority: number; /** Tree hypothesis or approach description */ readonly hypothesis: string; /** Best path(s) found in this tree */ readonly bestPaths: readonly PathScore[]; /** Tree statistics */ readonly statistics: TreeStatistics; /** Creation timestamp */ readonly createdAt: number; /** Last update timestamp */ readonly updatedAt: number; } /** * Schema for ReasoningTree validation (partial, excludes Map for JSON). */ declare const ReasoningTreeSchema: z.ZodObject<{ id: z.ZodString; forestId: z.ZodString; rootId: z.ZodString; state: z.ZodEnum<{ completed: "completed"; paused: "paused"; growing: "growing"; abandoned: "abandoned"; }>; overallScore: z.ZodNumber; explorationPriority: z.ZodNumber; hypothesis: z.ZodString; statistics: z.ZodObject<{ totalNodes: z.ZodNumber; activeNodes: z.ZodNumber; maxDepth: z.ZodNumber; avgQualityScore: z.ZodNumber; avgConfidence: z.ZodNumber; conclusionCount: z.ZodNumber; totalTokensUsed: z.ZodNumber; avgBranchingFactor: z.ZodNumber; }, z.core.$strip>; createdAt: z.ZodNumber; updatedAt: z.ZodNumber; }, z.core.$strip>; /** * Input for creating a new reasoning tree. */ interface CreateTreeInput { /** Forest ID this tree belongs to */ readonly forestId: ForestId; /** Tree hypothesis or approach */ readonly hypothesis: string; /** Initial exploration priority */ readonly explorationPriority?: number; } /** * nexus-agents/agents - Forest-of-Thought Configuration Types * * Configuration type definitions for Forest-of-Thought multi-tree * reasoning with sparse activation. * * @module agents/reasoning/forest-config-types * (Source: arXiv:2412.09078, Issue #331) */ /** * Strategy for selecting which nodes to activate. * * - `ucb`: Upper Confidence Bound (exploration/exploitation balance) * - `greedy`: Always activate highest-scoring nodes * - `diverse`: Prioritize diversity across trees * - `adaptive`: Dynamically adjust based on progress */ type ActivationStrategy = 'ucb' | 'greedy' | 'diverse' | 'adaptive'; /** * Schema for ActivationStrategy validation. */ declare const ActivationStrategySchema: z.ZodEnum<{ diverse: "diverse"; adaptive: "adaptive"; ucb: "ucb"; greedy: "greedy"; }>; /** * Strategy for sharing information across trees. * * - `none`: No cross-tree sharing * - `conclusions`: Share only conclusions * - `insights`: Share conclusions and intermediate insights * - `full`: Share all relevant information */ type CrossTreeStrategy = 'none' | 'conclusions' | 'insights' | 'full'; /** * Schema for CrossTreeStrategy validation. */ declare const CrossTreeStrategySchema: z.ZodEnum<{ none: "none"; insights: "insights"; full: "full"; conclusions: "conclusions"; }>; /** * Strategy for pruning low-quality branches. * * - `none`: No pruning * - `score`: Prune nodes below score threshold * - `depth`: Prune based on depth limits * - `combined`: Use both score and depth criteria */ type ForestPruningStrategy = 'none' | 'score' | 'depth' | 'combined'; /** * Schema for ForestPruningStrategy validation. */ declare const ForestPruningStrategySchema: z.ZodEnum<{ none: "none"; score: "score"; depth: "depth"; combined: "combined"; }>; /** * Configuration for Forest-of-Thought reasoning. */ interface ForestConfig { /** Maximum number of trees in the forest */ readonly maxTrees: number; /** Maximum depth per tree */ readonly maxDepth: number; /** Maximum nodes per tree */ readonly maxNodesPerTree: number; /** Total activation budget (max active nodes across forest) */ readonly activationBudget: number; /** Percentage of nodes to keep active (0-1) */ readonly sparsityRatio: number; /** Strategy for node activation */ readonly activationStrategy: ActivationStrategy; /** UCB exploration constant (for ucb strategy) */ readonly explorationConstant: number; /** Strategy for cross-tree information sharing */ readonly crossTreeStrategy: CrossTreeStrategy; /** Strategy for pruning low-quality branches */ readonly pruningStrategy: ForestPruningStrategy; /** Minimum score threshold for keeping nodes */ readonly minScoreThreshold: number; /** Confidence threshold for accepting conclusions */ readonly confidenceThreshold: number; /** Score threshold for early termination */ readonly earlyTerminationThreshold: number; /** Maximum exploration time in ms */ readonly maxExplorationTimeMs: number; /** Timeout per node evaluation in ms */ readonly nodeTimeoutMs: number; /** Maximum tokens per tree */ readonly maxTokensPerTree: number; /** Enable parallel tree exploration */ readonly enableParallelExploration: boolean; /** Number of parallel exploration threads */ readonly parallelThreads: number; /** Enable early termination when good solution found */ readonly enableEarlyTermination: boolean; /** Enable cross-tree information sharing */ readonly enableCrossTreeSharing: boolean; /** Temperature for node generation (creativity vs determinism) */ readonly temperature: number; /** Random seed for reproducibility (null for random) */ readonly seed: number | null; } /** * Schema for ForestConfig validation. */ declare const ForestConfigSchema: z.ZodObject<{ maxTrees: z.ZodDefault; maxDepth: z.ZodDefault; maxNodesPerTree: z.ZodDefault; activationBudget: z.ZodDefault; sparsityRatio: z.ZodDefault; activationStrategy: z.ZodDefault>; explorationConstant: z.ZodDefault; crossTreeStrategy: z.ZodDefault>; pruningStrategy: z.ZodDefault>; minScoreThreshold: z.ZodDefault; confidenceThreshold: z.ZodDefault; earlyTerminationThreshold: z.ZodDefault; maxExplorationTimeMs: z.ZodDefault; nodeTimeoutMs: z.ZodDefault; maxTokensPerTree: z.ZodDefault; enableParallelExploration: z.ZodDefault; parallelThreads: z.ZodDefault; enableEarlyTermination: z.ZodDefault; enableCrossTreeSharing: z.ZodDefault; temperature: z.ZodDefault; seed: z.ZodDefault>; }, z.core.$strip>; /** * Default Forest-of-Thought configuration. */ declare const DEFAULT_FOREST_CONFIG: ForestConfig; /** * Options for sparse activation selection. */ interface ActivationOptions { /** Maximum nodes to activate */ readonly maxActive: number; /** Strategy for selection */ readonly strategy: ActivationStrategy; /** Minimum score to consider for activation */ readonly minScore: number; /** Ensure at least one node per active tree */ readonly ensureTreeCoverage: boolean; } /** * Default activation options. */ declare const DEFAULT_ACTIVATION_OPTIONS: ActivationOptions; /** * nexus-agents/agents - Forest State and Statistics Types * * Foundational types for Forest-of-Thought state tracking and statistics. * Extracted to break circular dependency between forest-types.ts and * forest-result-types.ts. * * @module agents/reasoning/forest-state-types * (Source: arXiv:2412.09078, Issue #331) * (Source: Issue #392 - Circular dependency resolution) */ /** * State of a forest of reasoning trees. * * - `initializing`: Forest is being set up * - `exploring`: Actively exploring trees * - `converging`: Trees are converging on solution(s) * - `completed`: Forest has finished exploration * - `timeout`: Exploration ended due to timeout */ type ForestState = 'initializing' | 'exploring' | 'converging' | 'completed' | 'timeout'; /** * Schema for ForestState validation. */ declare const ForestStateSchema: z.ZodEnum<{ timeout: "timeout"; completed: "completed"; initializing: "initializing"; exploring: "exploring"; converging: "converging"; }>; /** * Statistics about forest exploration. */ interface ForestStatistics { /** Total number of trees */ readonly totalTrees: number; /** Number of active trees */ readonly activeTrees: number; /** Total nodes across all trees */ readonly totalNodes: number; /** Total active nodes across all trees */ readonly totalActiveNodes: number; /** Maximum depth across all trees */ readonly maxDepth: number; /** Best path score found */ readonly bestPathScore: number; /** Average tree score */ readonly avgTreeScore: number; /** Total tokens used */ readonly totalTokensUsed: number; /** Total exploration time in ms */ readonly totalExplorationTimeMs: number; /** Activation ratio (active nodes / total nodes) */ readonly activationRatio: number; } /** * Schema for ForestStatistics validation. */ declare const ForestStatisticsSchema: z.ZodObject<{ totalTrees: z.ZodNumber; activeTrees: z.ZodNumber; totalNodes: z.ZodNumber; totalActiveNodes: z.ZodNumber; maxDepth: z.ZodNumber; bestPathScore: z.ZodNumber; avgTreeScore: z.ZodNumber; totalTokensUsed: z.ZodNumber; totalExplorationTimeMs: z.ZodNumber; activationRatio: z.ZodNumber; }, z.core.$strip>; /** * nexus-agents/agents - Forest-of-Thought Result Types * * Type definitions for Forest-of-Thought reasoning results, including * solutions, exploration events, and termination reasons. * * @module agents/reasoning/forest-result-types * (Source: arXiv:2412.09078, Issue #331) */ /** * Termination reason for forest exploration. */ type TerminationReason = 'solution_found' | 'convergence' | 'max_time' | 'max_tokens' | 'max_depth' | 'no_progress' | 'error'; /** * Schema for TerminationReason validation. */ declare const TerminationReasonSchema: z.ZodEnum<{ error: "error"; max_tokens: "max_tokens"; no_progress: "no_progress"; solution_found: "solution_found"; convergence: "convergence"; max_time: "max_time"; max_depth: "max_depth"; }>; /** * The best solution found by the forest. */ interface BestSolution { /** Tree that produced the solution */ readonly treeId: TreeId; /** Path to the solution */ readonly path: readonly NodeId[]; /** Solution node */ readonly conclusionNode: ReasoningNode; /** Overall confidence */ readonly confidence: number; /** Overall quality score */ readonly qualityScore: number; /** Combined score */ readonly combinedScore: number; } /** * Schema for BestSolution validation. */ declare const BestSolutionSchema: z.ZodObject<{ treeId: z.ZodString; path: z.ZodArray; conclusionNode: z.ZodObject<{ id: z.ZodString; treeId: z.ZodString; parentId: z.ZodNullable; children: z.ZodArray; depth: z.ZodNumber; stepType: z.ZodEnum<{ inference: "inference"; hypothesis: "hypothesis"; synthesis: "synthesis"; decomposition: "decomposition"; verification: "verification"; conclusion: "conclusion"; }>; content: z.ZodString; metadata: z.ZodObject<{ source: z.ZodOptional; tokensUsed: z.ZodOptional; generationTimeMs: z.ZodOptional; crossReferences: z.ZodOptional>; custom: z.ZodOptional>; }, z.core.$strip>; state: z.ZodEnum<{ error: "error"; completed: "completed"; pending: "pending"; pruned: "pruned"; active: "active"; }>; isActive: z.ZodBoolean; activationScore: z.ZodNumber; confidence: z.ZodNumber; qualityScore: z.ZodNumber; estimatedValue: z.ZodNumber; createdAt: z.ZodNumber; updatedAt: z.ZodNumber; }, z.core.$strip>; confidence: z.ZodNumber; qualityScore: z.ZodNumber; combinedScore: z.ZodNumber; }, z.core.$strip>; /** * Types of exploration events. */ type ExplorationEventType = 'tree_created' | 'node_created' | 'node_activated' | 'node_deactivated' | 'node_completed' | 'node_pruned' | 'path_scored' | 'cross_tree_share' | 'conclusion_reached' | 'tree_completed' | 'forest_converging' | 'forest_completed'; /** * Schema for ExplorationEventType validation. */ declare const ExplorationEventTypeSchema: z.ZodEnum<{ node_completed: "node_completed"; tree_created: "tree_created"; node_created: "node_created"; node_activated: "node_activated"; node_deactivated: "node_deactivated"; node_pruned: "node_pruned"; path_scored: "path_scored"; cross_tree_share: "cross_tree_share"; conclusion_reached: "conclusion_reached"; tree_completed: "tree_completed"; forest_converging: "forest_converging"; forest_completed: "forest_completed"; }>; /** * An event in the exploration history for debugging/analysis. */ interface ExplorationEvent { /** Timestamp */ readonly timestamp: number; /** Event type */ readonly eventType: ExplorationEventType; /** Tree ID involved */ readonly treeId?: TreeId; /** Node ID involved */ readonly nodeId?: NodeId; /** Additional details */ readonly details: Record; } /** * Schema for ExplorationEvent validation. */ declare const ExplorationEventSchema: z.ZodObject<{ timestamp: z.ZodNumber; eventType: z.ZodEnum<{ node_completed: "node_completed"; tree_created: "tree_created"; node_created: "node_created"; node_activated: "node_activated"; node_deactivated: "node_deactivated"; node_pruned: "node_pruned"; path_scored: "path_scored"; cross_tree_share: "cross_tree_share"; conclusion_reached: "conclusion_reached"; tree_completed: "tree_completed"; forest_converging: "forest_converging"; forest_completed: "forest_completed"; }>; treeId: z.ZodOptional; nodeId: z.ZodOptional; details: z.ZodRecord; }, z.core.$strip>; /** * Result of Forest-of-Thought reasoning. */ interface ForestResult { /** Forest ID */ readonly forestId: ForestId; /** Original problem */ readonly problem: string; /** Best solution found */ readonly bestSolution: BestSolution | null; /** All high-quality paths found */ readonly topPaths: readonly PathScore[]; /** All conclusions reached across trees */ readonly conclusions: readonly ReasoningNode[]; /** Final state of the forest */ readonly finalState: ForestState; /** Reason for termination */ readonly terminationReason: TerminationReason; /** Final statistics */ readonly statistics: ForestStatistics; /** Total duration in ms */ readonly durationMs: number; /** Total tokens used */ readonly totalTokensUsed: number; /** Exploration history for analysis */ readonly explorationHistory?: readonly ExplorationEvent[]; } /** * Schema for ForestResult validation (partial). */ declare const ForestResultSchema: z.ZodObject<{ forestId: z.ZodString; problem: z.ZodString; bestSolution: z.ZodNullable; conclusionNode: z.ZodObject<{ id: z.ZodString; treeId: z.ZodString; parentId: z.ZodNullable; children: z.ZodArray; depth: z.ZodNumber; stepType: z.ZodEnum<{ inference: "inference"; hypothesis: "hypothesis"; synthesis: "synthesis"; decomposition: "decomposition"; verification: "verification"; conclusion: "conclusion"; }>; content: z.ZodString; metadata: z.ZodObject<{ source: z.ZodOptional; tokensUsed: z.ZodOptional; generationTimeMs: z.ZodOptional; crossReferences: z.ZodOptional>; custom: z.ZodOptional>; }, z.core.$strip>; state: z.ZodEnum<{ error: "error"; completed: "completed"; pending: "pending"; pruned: "pruned"; active: "active"; }>; isActive: z.ZodBoolean; activationScore: z.ZodNumber; confidence: z.ZodNumber; qualityScore: z.ZodNumber; estimatedValue: z.ZodNumber; createdAt: z.ZodNumber; updatedAt: z.ZodNumber; }, z.core.$strip>; confidence: z.ZodNumber; qualityScore: z.ZodNumber; combinedScore: z.ZodNumber; }, z.core.$strip>>; topPaths: z.ZodArray; targetNodeId: z.ZodString; score: z.ZodNumber; breakdown: z.ZodObject<{ confidenceScore: z.ZodNumber; qualityScore: z.ZodNumber; coherenceScore: z.ZodNumber; depthFactor: z.ZodNumber; conclusionBonus: z.ZodNumber; }, z.core.$strip>; reachesConclusion: z.ZodBoolean; length: z.ZodNumber; }, z.core.$strip>>; finalState: z.ZodEnum<{ timeout: "timeout"; completed: "completed"; initializing: "initializing"; exploring: "exploring"; converging: "converging"; }>; terminationReason: z.ZodEnum<{ error: "error"; max_tokens: "max_tokens"; no_progress: "no_progress"; solution_found: "solution_found"; convergence: "convergence"; max_time: "max_time"; max_depth: "max_depth"; }>; statistics: z.ZodObject<{ totalTrees: z.ZodNumber; activeTrees: z.ZodNumber; totalNodes: z.ZodNumber; totalActiveNodes: z.ZodNumber; maxDepth: z.ZodNumber; bestPathScore: z.ZodNumber; avgTreeScore: z.ZodNumber; totalTokensUsed: z.ZodNumber; totalExplorationTimeMs: z.ZodNumber; activationRatio: z.ZodNumber; }, z.core.$strip>; durationMs: z.ZodNumber; totalTokensUsed: z.ZodNumber; explorationHistory: z.ZodOptional; treeId: z.ZodOptional; nodeId: z.ZodOptional; details: z.ZodRecord; }, z.core.$strip>>>; }, z.core.$strip>; /** * nexus-agents/agents - Forest-of-Thought Types * * Type definitions for Forest-of-Thought multi-tree reasoning with sparse * activation. This technique enables parallel exploration of multiple * reasoning paths for improved problem-solving on complex multi-step tasks. * * This is the main entry point that re-exports all forest-related types * and includes the Forest and ForestResult types. * * @module agents/reasoning/forest-types * (Source: arXiv:2412.09078, Issue #331) */ /** * A conclusion shared across trees for cross-pollination. */ interface SharedConclusion { /** Source tree ID */ readonly sourceTreeId: TreeId; /** Source node ID */ readonly sourceNodeId: NodeId; /** The conclusion content */ readonly content: string; /** Confidence in this conclusion */ readonly confidence: number; /** Quality score */ readonly qualityScore: number; } /** * Schema for SharedConclusion validation. */ declare const SharedConclusionSchema: z.ZodObject<{ sourceTreeId: z.ZodString; sourceNodeId: z.ZodString; content: z.ZodString; confidence: z.ZodNumber; qualityScore: z.ZodNumber; }, z.core.$strip>; /** * An insight shared across trees. */ interface SharedInsight { /** Source tree ID */ readonly sourceTreeId: TreeId; /** Source node ID */ readonly sourceNodeId: NodeId; /** The insight content */ readonly content: string; /** Relevance score for current exploration */ readonly relevance: number; } /** * Schema for SharedInsight validation. */ declare const SharedInsightSchema: z.ZodObject<{ sourceTreeId: z.ZodString; sourceNodeId: z.ZodString; content: z.ZodString; relevance: z.ZodNumber; }, z.core.$strip>; /** * A pattern that has been identified as ineffective. */ interface FailurePattern { /** Pattern description */ readonly pattern: string; /** Number of times this pattern failed */ readonly occurrences: number; /** Average quality score when this pattern appeared */ readonly avgFailureScore: number; } /** * Schema for FailurePattern validation. */ declare const FailurePatternSchema: z.ZodObject<{ pattern: z.ZodString; occurrences: z.ZodNumber; avgFailureScore: z.ZodNumber; }, z.core.$strip>; /** * Information shared across trees for cross-pollination. */ interface CrossTreeInfo { /** High-confidence conclusions found in other trees */ readonly sharedConclusions: readonly SharedConclusion[]; /** Useful intermediate results from other trees */ readonly sharedInsights: readonly SharedInsight[]; /** Patterns that have been proven ineffective */ readonly failurePatterns: readonly FailurePattern[]; } /** * Schema for CrossTreeInfo validation. */ declare const CrossTreeInfoSchema: z.ZodObject<{ sharedConclusions: z.ZodArray>; sharedInsights: z.ZodArray>; failurePatterns: z.ZodArray>; }, z.core.$strip>; /** * A forest of reasoning trees with sparse activation. * Coordinates multiple parallel reasoning approaches. */ interface Forest { /** Unique forest identifier */ readonly id: ForestId; /** Problem being solved */ readonly problem: string; /** All trees in the forest (id -> tree) */ readonly trees: ReadonlyMap; /** Current state of the forest */ readonly state: ForestState; /** Best paths across all trees */ readonly bestPaths: readonly PathScore[]; /** Cross-tree shared information */ readonly crossTreeInfo: CrossTreeInfo; /** Forest-wide statistics */ readonly statistics: ForestStatistics; /** Maximum number of active nodes (sparse activation budget) */ readonly activationBudget: number; /** Currently active tree IDs */ readonly activeTreeIds: readonly TreeId[]; /** Creation timestamp */ readonly createdAt: number; /** Last update timestamp */ readonly updatedAt: number; } /** * Input for creating a new forest. */ interface CreateForestInput { /** Problem to solve */ readonly problem: string; /** Initial configuration */ readonly config?: Partial; /** Initial tree hypotheses to explore */ readonly initialHypotheses?: readonly string[]; } /** * nexus-agents/agents - Context Curator * * Curates context for ICTM sub-agents by filtering, ranking, * and trimming context items to fit within token budgets. * * Prevents long-horizon degradation by ensuring each sub-agent * receives only the most relevant context subset. * * @see Issue #756 * @module agents/ictm/context-curator */ /** * Score an item by recency using exponential decay. * More recent items score higher. */ declare function scoreByRecency(item: CuratedContextItem, nowMs: number): number; /** * Score an item by importance (uses pre-assigned relevance). */ declare function scoreByImportance(item: CuratedContextItem): number; /** * Score an item using hybrid strategy (weighted average of recency + importance). */ declare function scoreByHybrid(item: CuratedContextItem, nowMs: number): number; /** * Curated context result. */ interface CurationResult { /** Selected context items, ordered by score (descending) */ items: CuratedContextItem[]; /** Total tokens used */ totalTokens: number; /** Number of items filtered out */ filteredCount: number; /** Number of items trimmed for token budget */ trimmedCount: number; } /** * Curate context items according to a context filter. * * Pipeline: filter by history → filter by relevance → rank by strategy → trim to budget. * * @param items - All available context items * @param filter - Context filter configuration from ICTM config * @param nowMs - Current timestamp in ms (defaults to Date.now()) * @returns Curated result with selected items and stats */ declare function curateContext(items: readonly CuratedContextItem[], filter: ContextFilter, nowMs?: number): CurationResult; /** * Estimate token count for a text string. * Uses a simple char/4 heuristic (same as preference-router-extractor). */ declare function estimateTokens$1(text: string): number; /** * Create a context item from raw text. */ declare function createContextItem(id: string, content: string, source: CuratedContextItem['source'], relevance: number, timestamp?: number): CuratedContextItem; /** * nexus-agents/agents - ICTM Factory * * Factory for creating expert agents from ICTM configurations * and inferring ICTM configs from subtask analysis. * * @see Issue #756 * @module agents/ictm/ictm-factory */ /** * Convert an ICTM config to an ExpertConfig for the existing expert factory. * * This bridges the ICTM pattern to the existing expert creation pipeline, * enabling backward compatibility with all existing expert infrastructure. */ declare function ictmToExpertConfig(ictm: ICTMConfig, subtaskId: string): ExpertConfig; /** * Infer an optimal ICTM configuration from a subtask and its parent task analysis. * * This is the core intelligence of the ICTM pattern — it analyzes the subtask * to determine the best instructions, context filter, tools, and model config. * * @param subtask - The subtask to create a sub-agent for * @param analysis - Analysis of the parent task * @returns ICTMInferenceResult with config and reasoning */ declare function inferICTM(subtask: SubTask, analysis: TaskAnalysis): ICTMInferenceResult; /** * Validate an ICTM config using Zod schema. * Returns the validated config or null on failure. */ declare function validateICTM(config: unknown): ICTMConfig | null; /** * Get the recommended expert role for a task type. * Falls back to 'code_expert' for unknown types. */ declare function getRecommendedRole(taskType: string): string; /** * nexus-agents/workflows - Workflow Parser * * Parses and validates workflow definitions from YAML and JSON formats. * Uses Zod schemas for runtime validation at the parsing boundary. */ /** * Parses a YAML string into a WorkflowDefinition. * @param content - YAML string content * @returns Result with WorkflowDefinition or ParseError */ declare function parseWorkflowYaml(content: string): Result; /** * Parses a JSON string into a WorkflowDefinition. * @param content - JSON string content * @returns Result with WorkflowDefinition or ParseError */ declare function parseWorkflowJson(content: string): Result; /** * Loads and parses a workflow definition from a file. * @param filePath - Path to the workflow file * @param allowedRoot - Root directory for path validation (defaults to process.cwd()) * @returns Result with WorkflowDefinition or ParseError/SecurityError */ declare function loadWorkflowFile(filePath: string, allowedRoot?: string): Promise>; /** * Validates a WorkflowDefinition object. * Useful for validating programmatically created workflows. * @param workflow - WorkflowDefinition to validate * @returns Result with void or ParseError */ declare function validateWorkflow(workflow: WorkflowDefinition): Result; /** * nexus-agents/workflows - Workflow Types * * Zod schemas for runtime validation of workflow definitions. * These schemas validate YAML/JSON workflow templates at parse time. */ /** * Input types supported in workflow definitions. */ declare const InputTypeSchema: z.ZodEnum<{ string: "string"; number: "number"; boolean: "boolean"; object: "object"; array: "array"; }>; type InputType = z.infer; /** * Schema for workflow input definitions. * Inputs are parameters that must be provided when executing a workflow. */ declare const InputDefinitionSchema$1: z.ZodObject<{ name: z.ZodString; type: z.ZodEnum<{ string: "string"; number: "number"; boolean: "boolean"; object: "object"; array: "array"; }>; description: z.ZodOptional; required: z.ZodDefault; default: z.ZodOptional; }, z.core.$strict>; type InputDefinitionInput = z.input; type InputDefinitionOutput = z.output; /** * Agent roles that can execute workflow steps. */ declare const AgentRoleSchema$1: z.ZodEnum<{ custom: "custom"; orchestrator: "orchestrator"; code_expert: "code_expert"; architecture_expert: "architecture_expert"; security_expert: "security_expert"; documentation_expert: "documentation_expert"; testing_expert: "testing_expert"; infrastructure_expert: "infrastructure_expert"; }>; type AgentRoleType = z.infer; /** * Schema for a single workflow step. * Steps are the atomic units of work in a workflow. */ declare const WorkflowStepSchema$1: z.ZodObject<{ id: z.ZodString; agent: z.ZodEnum<{ custom: "custom"; orchestrator: "orchestrator"; code_expert: "code_expert"; architecture_expert: "architecture_expert"; security_expert: "security_expert"; documentation_expert: "documentation_expert"; testing_expert: "testing_expert"; infrastructure_expert: "infrastructure_expert"; }>; action: z.ZodString; inputs: z.ZodDefault>; dependsOn: z.ZodOptional>; parallel: z.ZodOptional; retries: z.ZodOptional; timeout: z.ZodOptional; condition: z.ZodOptional; contextBudget: z.ZodOptional; task: z.ZodOptional; active: z.ZodOptional; reserved: z.ZodOptional; }, z.core.$strip>>; }, z.core.$strict>; type WorkflowStepInput = z.input; type WorkflowStepOutput = z.output; /** * Alias for WorkflowStepOutput for use in engine/execution code. * This provides a cleaner name for runtime usage. */ type WorkflowStep = WorkflowStepOutput; /** * Schema for a complete workflow definition. * This is the top-level structure of a workflow template file. */ declare const WorkflowDefinitionSchema$1: z.ZodObject<{ name: z.ZodString; version: z.ZodString; description: z.ZodOptional; inputs: z.ZodDefault; description: z.ZodOptional; required: z.ZodDefault; default: z.ZodOptional; }, z.core.$strict>>>; steps: z.ZodArray; action: z.ZodString; inputs: z.ZodDefault>; dependsOn: z.ZodOptional>; parallel: z.ZodOptional; retries: z.ZodOptional; timeout: z.ZodOptional; condition: z.ZodOptional; contextBudget: z.ZodOptional; task: z.ZodOptional; active: z.ZodOptional; reserved: z.ZodOptional; }, z.core.$strip>>; }, z.core.$strict>>; timeout: z.ZodOptional; defaultBudget: z.ZodOptional>; }, z.core.$strict>; type WorkflowDefinitionInput = z.input; type WorkflowDefinitionOutput = z.output; /** * Validation result with detailed error information. */ interface ValidationIssue { /** Path to the problematic field */ path: PropertyKey[]; /** Error message */ message: string; /** Error code from Zod */ code: string; } /** * nexus-agents/workflows - Dependency Graph * * Builds and validates step dependency graphs for workflow definitions. * Detects circular dependencies using Kahn's algorithm for topological sort. */ /** * Represents a node in the dependency graph. */ interface GraphNode$1 { /** Step ID */ id: string; /** IDs of steps this node depends on */ dependencies: Set; /** IDs of steps that depend on this node */ dependents: Set; } /** * Dependency graph for workflow steps. */ declare class DependencyGraph { private readonly nodes; /** * Adds a step to the graph. * @param step - The workflow step to add */ addStep(step: WorkflowStep$1): void; /** * Builds the reverse dependency links (dependents). */ buildReverseLinks(): void; /** * Gets all step IDs in the graph. */ getStepIds(): string[]; /** * Gets a node by step ID. */ getNode(id: string): GraphNode$1 | undefined; /** * Validates that all dependency references exist. * @returns Result with void or ParseError containing missing references */ validateReferences(): Result; /** * Validates that all step IDs are unique. * @param steps - Array of workflow steps * @returns Result with void or ParseError for duplicates */ static validateUniqueIds(steps: WorkflowStep$1[]): Result; /** * Initializes in-degree map for Kahn's algorithm. */ private initializeInDegrees; /** * Gets initial queue of nodes with zero dependencies. */ private getInitialQueue; /** * Processes a single node in Kahn's algorithm. */ private processNode; /** * Detects circular dependencies using Kahn's algorithm. * @returns Result with topologically sorted step IDs or ParseError for cycles */ detectCycles(): Result; /** * Creates error for detected cycle. */ private createCycleError; /** * Finds a cycle path starting from one of the cycle nodes. * Uses DFS to trace back through dependencies. * @param cycleNodes - Nodes known to be in cycles * @returns Array of step IDs forming a cycle */ private findCyclePath; /** * Gets the execution order (topologically sorted step IDs). * @returns Result with sorted step IDs or ParseError */ getExecutionOrder(): Result; } /** * Builds a dependency graph from a workflow definition. * @param workflow - The workflow definition * @returns The constructed dependency graph */ declare function buildDependencyGraph(workflow: WorkflowDefinition): DependencyGraph; /** * Validates the dependency graph of a workflow. * Checks for: * - Duplicate step IDs * - Missing step references * - Circular dependencies * * @param workflow - The workflow definition to validate * @returns Result with void or ParseError */ declare function validateDependencyGraph(workflow: WorkflowDefinition): Result; /** * Gets the topologically sorted execution order for a workflow. * Used for parsing validation (returns ParseError). * For execution planning, use createExecutionPlan from execution-planner. * * @param workflow - The workflow definition * @returns Result with sorted step IDs or ParseError */ declare function getTopologicalOrder(workflow: WorkflowDefinition): Result; /** * nexus-agents/workflows - Task Queue * * Simple task queue for limiting concurrent task execution. * Provides cancellation support via AbortController. */ /** * Task function type. */ type Task = (signal: AbortSignal) => Promise; /** * A task queue that limits concurrent execution. * * @template T - The return type of tasks in this queue */ declare class TaskQueue { private readonly concurrency; private readonly queue; private running; private readonly abortController; private cancelled; /** * Creates a new TaskQueue. * * @param concurrency - Maximum number of concurrent tasks (default: 5) */ constructor(concurrency?: number); /** * Adds a task to the queue for execution. * * @param task - The async task to execute * @returns Promise that resolves with the task result * @throws Error if the queue has been cancelled */ add(task: Task): Promise; /** * Cancels all pending and running tasks. * Running tasks receive an abort signal. */ cancel(): void; /** * Returns whether the queue has been cancelled. */ isCancelled(): boolean; /** * Returns the number of currently running tasks. */ getRunningCount(): number; /** * Returns the number of tasks waiting in the queue. */ getQueuedCount(): number; /** * Returns the abort signal for external use. */ getAbortSignal(): AbortSignal; /** * Processes the next task in the queue if capacity allows. */ private processNext; } /** * Creates a task queue with the specified concurrency. * * @param concurrency - Maximum number of concurrent tasks * @returns A new TaskQueue instance */ declare function createTaskQueue(concurrency?: number): TaskQueue; /** * nexus-agents/workflows - Execution Planner * * Creates execution plans with phases based on step dependencies. * Uses topological sort to group independent steps into concurrent phases. */ /** * A phase of steps that can be executed concurrently. */ interface ExecutionPhase$1 { /** Steps that can run in parallel within this phase */ steps: WorkflowStep$1[]; /** Phase index (0-based) */ phaseIndex: number; } /** * Execution plan with ordered phases. */ interface ExecutionPlan$1 { /** Ordered phases of execution */ phases: ExecutionPhase$1[]; /** Total number of steps */ totalSteps: number; /** Maximum parallelism (max steps in any phase) */ maxParallelism: number; } /** * Creates an execution plan from a workflow definition. * Groups steps into phases based on dependencies for parallel execution. * * @param workflow - Workflow definition to analyze * @returns Result with ExecutionPlan or WorkflowError */ declare function createExecutionPlan(workflow: WorkflowDefinition): Result; /** * Validates a workflow definition without creating a full plan. * * @param workflow - Workflow definition to validate * @returns Result with void or WorkflowError */ declare function validateWorkflowDependencies(workflow: WorkflowDefinition): Result; /** * Gets the execution order of steps as a flat array. * Steps in the same phase are grouped together. * * @param plan - Execution plan * @returns Ordered array of step IDs */ declare function getExecutionOrder(plan: ExecutionPlan$1): string[]; /** * nexus-agents/workflows - Parallel Executor * * Executes workflow steps in parallel with concurrency limiting, * fail-fast behavior, and cancellation support. */ /** * Options for parallel execution. */ interface ParallelOptions { /** Maximum concurrent steps (default: 5) */ maxConcurrency?: number; /** Stop on first error (default: true) */ failFast?: boolean; /** Overall timeout in milliseconds */ timeoutMs?: number; } /** * Context passed to step executor. */ interface ExecutionContext$1 { /** Workflow execution ID */ executionId: string; /** Results from previous steps */ stepResults: Map; /** Workflow inputs */ inputs: Record; /** Abort signal for cancellation */ signal?: AbortSignal; } /** * Function signature for step execution. */ type StepExecutor$1 = (step: WorkflowStep$1, context: ExecutionContext$1) => Promise; /** * Executes steps in parallel with concurrency limiting. */ declare function executeParallel(steps: WorkflowStep$1[], context: ExecutionContext$1, stepExecutor: StepExecutor$1, options?: ParallelOptions): Promise>; /** * nexus-agents/workflows - Template Types * * Type definitions and Zod schemas for workflow templates. */ /** * Template category for organization. */ type TemplateCategory = 'development' | 'review' | 'documentation' | 'testing' | 'custom'; /** * Extended template metadata for registry. * Implements IRegistryItem for unified registry API (ADR-0012). */ interface TemplateMetadata extends WorkflowTemplate { /** Unique identifier (alias for name, required by IRegistryItem) */ readonly id: string; /** Template category */ category: TemplateCategory; /** Keywords for search */ keywords: string[]; /** Whether this is a built-in template */ builtIn: boolean; /** Template author */ author?: string; /** Last updated timestamp */ updatedAt?: string; } /** * Template registry interface. */ interface ITemplateRegistry { /** * Get all built-in templates. * @returns Array of built-in template metadata */ getBuiltIn(): TemplateMetadata[]; /** * Get all registered templates (built-in + custom). * @returns Array of all template metadata */ getAll(): TemplateMetadata[]; /** * Get a workflow definition by template ID. * @param id - Template name/ID * @returns WorkflowDefinition or undefined if not found */ getById(id: string): WorkflowDefinition | undefined; /** * Register a custom workflow template. * @param workflow - Workflow definition to register * @param metadata - Optional additional metadata */ register(workflow: WorkflowDefinition, metadata?: Partial): void; /** * Unregister a custom template by ID. * @param id - Template ID to unregister * @returns True if template was removed */ unregister(id: string): boolean; /** * Load templates from a directory. * @param directoryPath - Path to directory containing YAML templates * @returns Number of templates loaded */ loadFromDirectory(directoryPath: string): Promise; /** * Search templates by keyword. * @param query - Search query * @returns Matching template metadata */ search(query: string): TemplateMetadata[]; /** * Get templates by category. * @param category - Category to filter by * @returns Templates in the category */ getByCategory(category: TemplateCategory): TemplateMetadata[]; } /** * Input definition schema. */ declare const InputDefinitionSchema: z.ZodObject<{ name: z.ZodString; type: z.ZodEnum<{ string: "string"; number: "number"; boolean: "boolean"; object: "object"; array: "array"; }>; description: z.ZodOptional; required: z.ZodDefault>; default: z.ZodOptional; }, z.core.$strip>; /** * Agent role schema. * Must match AgentRole type in core/types/agent.ts. */ declare const AgentRoleSchema: z.ZodEnum<{ custom: "custom"; orchestrator: "orchestrator"; code_expert: "code_expert"; architecture_expert: "architecture_expert"; security_expert: "security_expert"; documentation_expert: "documentation_expert"; testing_expert: "testing_expert"; devops_expert: "devops_expert"; research_expert: "research_expert"; infrastructure_expert: "infrastructure_expert"; thinker: "thinker"; worker: "worker"; verifier: "verifier"; }>; /** * Workflow step schema. */ declare const WorkflowStepSchema: z.ZodObject<{ id: z.ZodString; agent: z.ZodEnum<{ custom: "custom"; orchestrator: "orchestrator"; code_expert: "code_expert"; architecture_expert: "architecture_expert"; security_expert: "security_expert"; documentation_expert: "documentation_expert"; testing_expert: "testing_expert"; devops_expert: "devops_expert"; research_expert: "research_expert"; infrastructure_expert: "infrastructure_expert"; thinker: "thinker"; worker: "worker"; verifier: "verifier"; }>; action: z.ZodString; description: z.ZodOptional; inputs: z.ZodDefault>; dependsOn: z.ZodOptional>; parallel: z.ZodDefault>; retries: z.ZodOptional; timeout: z.ZodOptional; condition: z.ZodOptional; }, z.core.$strip>; /** * Workflow definition schema for YAML parsing. * Validates and transforms YAML content into WorkflowDefinition. */ declare const WorkflowDefinitionSchema: z.ZodPipe; inputs: z.ZodDefault; description: z.ZodOptional; required: z.ZodDefault>; default: z.ZodOptional; }, z.core.$strip>>>; steps: z.ZodArray; action: z.ZodString; description: z.ZodOptional; inputs: z.ZodDefault>; dependsOn: z.ZodOptional>; parallel: z.ZodDefault>; retries: z.ZodOptional; timeout: z.ZodOptional; condition: z.ZodOptional; }, z.core.$strip>>; timeout: z.ZodOptional; }, z.core.$strip>, z.ZodTransform<{ name: string; version: string; description: string | undefined; inputs: { name: string; type: "string" | "number" | "boolean" | "object" | "array"; description: string | undefined; required: boolean; default: unknown; }[]; steps: { id: string; agent: "custom" | "orchestrator" | "code_expert" | "architecture_expert" | "security_expert" | "documentation_expert" | "testing_expert" | "devops_expert" | "research_expert" | "infrastructure_expert" | "thinker" | "worker" | "verifier"; action: string; inputs: Record; dependsOn: string[] | undefined; parallel: boolean; retries: number | undefined; timeout: number | undefined; condition: string | undefined; }[]; timeout: number | undefined; }, { name: string; version: string; inputs: { name: string; type: "string" | "number" | "boolean" | "object" | "array"; required: boolean; description?: string | undefined; default?: unknown; }[]; steps: { id: string; agent: "custom" | "orchestrator" | "code_expert" | "architecture_expert" | "security_expert" | "documentation_expert" | "testing_expert" | "devops_expert" | "research_expert" | "infrastructure_expert" | "thinker" | "worker" | "verifier"; action: string; inputs: Record; parallel: boolean; description?: string | undefined; dependsOn?: string[] | undefined; retries?: number | undefined; timeout?: number | undefined; condition?: string | undefined; }[]; description?: string | undefined; timeout?: number | undefined; }>>; /** * Template category schema. */ declare const TemplateCategorySchema: z.ZodEnum<{ custom: "custom"; documentation: "documentation"; testing: "testing"; review: "review"; development: "development"; }>; /** * Template metadata schema. */ declare const TemplateMetadataSchema: z.ZodObject<{ name: z.ZodString; version: z.ZodString; description: z.ZodOptional; path: z.ZodString; category: z.ZodEnum<{ custom: "custom"; documentation: "documentation"; testing: "testing"; review: "review"; development: "development"; }>; keywords: z.ZodDefault>; builtIn: z.ZodDefault; author: z.ZodOptional; updatedAt: z.ZodOptional; }, z.core.$strip>; /** * Built-in template names. */ declare const BUILT_IN_TEMPLATES: readonly ["code-review", "docs-audit", "feature-implementation", "bug-fix", "documentation-update", "infrastructure-audit", "refactoring", "research-review", "security-audit", "standards-review", "test-generation"]; type BuiltInTemplateName = (typeof BUILT_IN_TEMPLATES)[number]; /** * Category mapping for built-in templates. */ declare const TEMPLATE_CATEGORIES: Record; /** * Keywords for built-in templates. */ declare const TEMPLATE_KEYWORDS: Record; /** * nexus-agents/workflows - Template Loader * * Utilities for loading and parsing YAML workflow templates. */ /** * Result of parsing a template file. */ interface ParsedTemplate { definition: WorkflowDefinition; metadata: TemplateMetadata; } /** * Get the directory containing built-in templates. * * Handles both development (unbundled) and production (bundled) scenarios: * - Development: import.meta.url points to src/workflows/template-loader.ts * - Production: import.meta.url points to dist/index.js or dist/cli.js * * @returns Path to templates directory */ declare function getBuiltInTemplatesPath(): string; /** * Parse a YAML template string into a WorkflowDefinition. * @param content - YAML content to parse * @param filePath - Path to the file (for error messages) * @returns Result with WorkflowDefinition or ParseError */ declare function parseTemplateContent(content: string, filePath: string): Result; /** * Load a template from a file path. * @param filePath - Path to the YAML template file * @param allowedRoot - Optional root directory for path validation (skipped if undefined) * @returns Result with ParsedTemplate or ParseError/SecurityError */ declare function loadTemplateFile(filePath: string, allowedRoot?: string): Promise>; /** * Load all templates from a directory. * Validates each file path to prevent path traversal attacks. * @param directoryPath - Path to directory containing YAML templates * @returns Array of successfully loaded templates and any errors */ declare function loadTemplatesFromDirectory(directoryPath: string): Promise<{ templates: ParsedTemplate[]; errors: Array; }>; /** * Load all built-in templates. * @returns Map of template name to WorkflowDefinition */ declare function getBuiltInTemplates(): Promise>; /** * Load built-in templates with full metadata. * @returns Array of parsed templates with metadata */ declare function getBuiltInTemplatesWithMetadata(): Promise; /** * nexus-agents/workflows - Template Registry * * Registry for managing workflow templates (built-in and custom). * Implements IRegistry (ADR-0012). */ /** * Error specific to template registry operations. */ declare class TemplateRegistryError extends AgentError$1 { constructor(message: string, options?: { cause?: Error; context?: Record; }); } /** * Template registry implementation. * Manages both built-in and custom workflow templates. */ declare class TemplateRegistry implements ITemplateRegistry { private readonly definitions; private readonly metadata; private initialized; private initPromise; /** * Initialize the registry with built-in templates. * Called automatically on first access if not already initialized. * Uses promise coalescing to prevent duplicate init from concurrent calls. */ initialize(): Promise; private doInitialize; /** * Ensure registry is initialized. */ private ensureInitialized; /** * Get all built-in templates. */ getBuiltIn(): TemplateMetadata[]; /** * Get all registered templates. */ getAll(): TemplateMetadata[]; /** * Get a workflow definition by ID. */ getById(id: string): WorkflowDefinition | undefined; /** * Register a custom workflow template. */ register(workflow: WorkflowDefinition, partialMetadata?: Partial): void; /** * Validate that a template can be registered. */ private validateCanRegister; /** * Build metadata for a workflow. */ private buildMetadata; /** * Unregister a custom template. */ unregister(id: string): boolean; /** * Load templates from a directory. */ loadFromDirectory(directoryPath: string): Promise; /** * Search templates by keyword. */ search(query: string): TemplateMetadata[]; /** * Check if metadata matches a search query. */ private matchesQuery; /** * Get templates by category. */ getByCategory(category: TemplateCategory): TemplateMetadata[]; /** * Clear all custom templates (keeps built-in). */ clearCustom(): void; /** * Get template metadata by ID. * IRegistry interface method. * * @param id - Template ID to retrieve * @returns Result with TemplateMetadata or TemplateRegistryError */ get(id: string): Result; /** * Check if a template is registered. * IRegistry interface method. * * @param id - Template ID to check * @returns True if template is registered */ has(id: string): boolean; /** * Get all registered template IDs. * IRegistry interface method. * * @returns Array of all registered template IDs */ getAllIds(): string[]; /** * Query templates with predicate function. * IRegistry interface method. * * @param predicate - Function to test each template * @returns Array of matching templates */ query(predicate: (item: TemplateMetadata) => boolean): TemplateMetadata[]; /** * Get the number of registered templates. * IRegistry interface method. */ get size(): number; /** * Check if the registry is empty. * IRegistry interface method. */ get isEmpty(): boolean; /** * Clear all templates (built-in and custom). * IRegistry interface method. * * WARNING: This removes built-in templates. Use clearCustom() to only clear custom templates. */ clear(): void; /** * Get registry statistics. * IRegistry interface method with domain-specific extensions. */ getStats(): IRegistryStats & { builtIn: number; custom: number; }; } /** * Create or get the template registry instance. * @returns Template registry instance */ declare function createTemplateRegistry(): ITemplateRegistry; /** * Create a new isolated template registry instance. * Useful for testing or isolated contexts. * @returns New template registry instance */ declare function createIsolatedRegistry(): TemplateRegistry; /** * Reset the global registry instance. * Primarily for testing purposes. */ declare function resetRegistry(): void; /** * nexus-agents/workflows - Execution Context * * Manages execution state and variable resolution for workflow steps. * Provides context isolation and result tracking during workflow execution. */ /** * Full execution context for a running workflow. * Tracks step results, variables, and provides input resolution. * This is the comprehensive context used by the step executor. */ interface WorkflowExecutionContext { /** Workflow definition ID */ readonly workflowId: string; /** Unique execution instance ID */ readonly executionId: string; /** Initial workflow inputs */ readonly inputs: Record; /** Results from completed steps (stepId -> result) */ readonly stepResults: Map; /** Runtime variables set during execution */ readonly variables: Map; /** Execution start time */ readonly startedAt: Date; /** Whether execution has been cancelled */ cancelled: boolean; } /** * Schema for validating workflow inputs. */ declare const WorkflowInputsSchema: z.ZodRecord; /** * Options for creating an execution context. */ interface CreateExecutionContextOptions { /** Workflow definition ID */ workflowId: string; /** Workflow inputs */ inputs: Record; /** Optional custom execution ID (auto-generated if not provided) */ executionId?: string; } /** * Creates a new execution context for a workflow run. * * @param options - Context creation options * @returns A new WorkflowExecutionContext instance */ declare function createExecutionContext(options: CreateExecutionContextOptions): WorkflowExecutionContext; /** * Stores a step result in the execution context. * * @param context - The execution context * @param stepId - The step identifier * @param result - The step result to store */ declare function storeStepResult(context: WorkflowExecutionContext, stepId: string, result: StepResult): void; /** * Retrieves a step result from the execution context. * * @param context - The execution context * @param stepId - The step identifier * @returns The step result or undefined if not found */ declare function getStepResult(context: WorkflowExecutionContext, stepId: string): StepResult | undefined; /** * Sets a variable in the execution context. * * @param context - The execution context * @param name - Variable name * @param value - Variable value */ declare function setVariable(context: WorkflowExecutionContext, name: string, value: unknown): void; /** * Gets a variable from the execution context. * * @param context - The execution context * @param name - Variable name * @returns The variable value or undefined */ declare function getVariable(context: WorkflowExecutionContext, name: string): unknown; /** * Gets all completed step IDs. * * @param context - The execution context * @returns Array of completed step IDs */ declare function getCompletedSteps(context: WorkflowExecutionContext): string[]; /** * Checks if a step has been completed. * * @param context - The execution context * @param stepId - The step identifier * @returns True if step is completed */ declare function isStepCompleted(context: WorkflowExecutionContext, stepId: string): boolean; /** * Checks if all specified steps are completed. * * @param context - The execution context * @param stepIds - Array of step identifiers to check * @returns True if all specified steps are completed */ declare function areStepsCompleted(context: WorkflowExecutionContext, stepIds: string[]): boolean; /** * Gets the execution duration in milliseconds. * * @param context - The execution context * @returns Duration in milliseconds */ declare function getExecutionDuration(context: WorkflowExecutionContext): number; /** * Marks the execution as cancelled. * * @param context - The execution context */ declare function cancelExecution(context: WorkflowExecutionContext): void; /** * Checks if the execution has been cancelled. * * @param context - The execution context * @returns True if cancelled */ declare function isCancelled(context: WorkflowExecutionContext): boolean; /** * Creates a snapshot of the current context state. * Useful for debugging and logging. * * @param context - The execution context * @returns A plain object snapshot */ declare function snapshotContext(context: WorkflowExecutionContext): Record; /** * Validates that required inputs are present. * * @param inputs - The inputs to validate * @param required - Array of required input names * @returns Validation error or null if valid */ declare function validateRequiredInputs(inputs: Record, required: string[]): ValidationError$1 | null; /** * nexus-agents/workflows - Expression Resolver Types * * Type definitions for expression resolution. * Extracted to avoid circular dependencies. */ /** * Types of expression references. */ type ExpressionType = 'inputs' | 'steps' | 'variables'; /** * Parsed expression structure. */ interface ParsedExpression { /** Original expression string */ original: string; /** Expression type (inputs, steps, variables) */ type: ExpressionType; /** Path segments after the type */ path: string[]; } /** * Result of expression resolution. */ interface ResolveResult { /** Whether resolution succeeded */ success: boolean; /** Resolved value if successful */ value?: unknown; /** Error message if failed */ error?: string; } /** * nexus-agents/workflows - Expression Resolver * * Parses and resolves ${{ }} template expressions in workflow step inputs. * Supports accessing workflow inputs, step outputs, and variables. * * Expression syntax: * - ${{ inputs.name }} - Access workflow input * - ${{ steps.stepId.output }} - Access step output * - ${{ steps.stepId.output.field }} - Access nested field in step output * - ${{ variables.name }} - Access runtime variable */ /** * Parses an expression string into its components. * * @param expression - The expression content (without ${{ }}) * @returns Parsed expression or null if invalid */ declare function parseExpression(expression: string): ParsedExpression | null; /** * Resolves a single parsed expression against the context. * * @param parsed - Parsed expression * @param context - Execution context * @returns Resolve result */ declare function resolveExpression(parsed: ParsedExpression, context: WorkflowExecutionContext): ResolveResult; /** * Checks if a value contains expression patterns. * * @param value - Value to check * @returns True if value contains expressions */ declare function containsExpressions(value: unknown): boolean; /** * Resolves all expressions in a string value. * * If the entire string is a single expression, returns the resolved value. * If the string contains multiple expressions or mixed content, returns a string * with all expressions replaced by their resolved values. */ declare function resolveStringExpressions(value: string, context: WorkflowExecutionContext): unknown; /** * Recursively resolves expressions in a value. * * Handles strings, arrays, and objects. Primitives other than strings * are returned unchanged. * * @param input - Value containing potential expressions * @param context - Execution context * @returns Resolved value * @throws ValidationError if resolution fails */ declare function resolveInput(input: unknown, context: WorkflowExecutionContext): unknown; /** * Validates that all expressions in a value can be resolved. * Does not actually resolve them, just checks validity. * * @param input - Value containing potential expressions * @param context - Execution context * @returns Array of validation errors (empty if all valid) */ declare function validateExpressions(input: unknown, context: WorkflowExecutionContext): string[]; /** * Extracts all expression references from a value. * Useful for determining step dependencies. * * @param input - Value containing potential expressions * @returns Array of parsed expressions */ declare function extractExpressions(input: unknown): ParsedExpression[]; /** * Gets all step IDs referenced in expressions within a value. * * @param input - Value containing potential expressions * @returns Array of referenced step IDs */ declare function getReferencedSteps(input: unknown): string[]; /** * nexus-agents/workflows - Step Executor * * Executes individual workflow steps using agent experts. * Handles input resolution, error handling, retries, timeouts, and conditions. * * Helper functions extracted to step-executor-helpers.ts. */ /** * Interface for expert factory dependency. */ interface IExpertFactory$1 { createForRole(role: AgentRole): Result; } /** * Wrapper to adapt ExpertFactory to IExpertFactory interface. */ declare class ExpertFactoryAdapter implements IExpertFactory$1 { private readonly factory; constructor(factory: typeof ExpertFactory); createForRole(role: AgentRole): Result; } /** Dependencies for the step executor. */ interface StepExecutorDeps { expertFactory: IExpertFactory$1; logger?: { debug: (message: string, data?: Record) => void; info: (message: string, data?: Record) => void; warn: (message: string, data?: Record) => void; error: (message: string, data?: Record) => void; }; } /** Options for step execution. */ interface StepExecutionOptions { timeoutMs?: number; retries?: number; retryDelayMs?: number; } /** * Executor for individual workflow steps. */ declare class StepExecutor { private readonly deps; constructor(deps: StepExecutorDeps); execute(step: WorkflowStep$1, context: WorkflowExecutionContext, options?: StepExecutionOptions): Promise>; private preExecutionChecks; private resolveStepInputs; private getRetryParams; private createCancelledError; private executeWithRetries; private checkDependencies; private executeAttempt; private runExpertWithTimeout; private handleExecutionError; private cleanupExpert; } /** * Creates a new StepExecutor instance. */ declare function createStepExecutor(deps: StepExecutorDeps): StepExecutor; /** * Workflow Engine Helpers - Pure helper functions and types for WorkflowEngine. * * This module contains constants, types, and pure functions extracted from * workflow-engine.ts to keep the main file under 400 lines. */ /** Configuration for workflow engine. */ interface WorkflowEngineConfig { defaultTimeoutMs?: number; maxConcurrency?: number; templatePaths?: string[]; contextManagerConfig?: Omit; defaultBudget?: ContextBudget$1; logger?: ILogger; } /** Execution plan with phases. */ interface ExecutionPlan { phases: ExecutionPhase[]; } /** Single execution phase (all steps run concurrently). */ interface ExecutionPhase { steps: WorkflowStep[]; } /** Execution context for workflow. */ interface ExecutionContext { workflowId: string; executionId: string; inputs: Record; stepResults: Map; variables: Map; abortController: AbortController; contextManager: ContextManager | undefined; } /** Options for phase execution. */ interface ExecutionOptions { maxConcurrency: number; failFast: boolean; timeoutMs?: number; } /** * Workflow Engine Types - Interface definitions for WorkflowEngine. * * This module contains dependency interfaces and internal tracking types * extracted from workflow-engine.ts to keep files under 400 lines. */ /** Dependencies for workflow engine. */ interface WorkflowEngineDeps { parseWorkflow: (content: string, format: 'yaml' | 'json') => Result; loadWorkflowFile: (path: string) => Promise>; createExecutionPlan: (workflow: WorkflowDefinition) => Result; executePhase: (steps: WorkflowStep[], context: ExecutionContext, options: ExecutionOptions) => Promise>; getBuiltInTemplates: () => Map; } /** * nexus-agents/workflows - Workflow Engine Factory * * Factory function to create WorkflowEngine with real dependencies. * Wires up the parser, loader, planner, and executor components. * * @module workflows/workflow-engine-factory */ /** * Configuration for the workflow engine factory. */ interface WorkflowEngineFactoryConfig extends WorkflowEngineConfig { /** Pre-loaded built-in templates (if not provided, loads at creation time) */ builtInTemplates?: Map; /** Optional pre-configured model adapter for expert agents */ modelAdapter?: IModelAdapter; /** Optional expert factory for dependency injection (useful for testing) */ expertFactory?: IExpertFactory$1; /** Use mock executor instead of real StepExecutor (default: false when expertFactory provided) */ useMockExecutor?: boolean; } /** * Creates WorkflowEngineDeps with real implementations. * * When expertFactory is provided in config, the workflow engine will use the real * StepExecutor to execute steps with agent experts. Otherwise, uses a mock executor. * * @param config - Factory configuration * @returns WorkflowEngineDeps instance */ declare function createWorkflowEngineDeps(config?: WorkflowEngineFactoryConfig): WorkflowEngineDeps; /** * Initializes and caches built-in templates. * Call this at startup before creating workflow engines. * * @returns Promise that resolves when templates are loaded */ declare function initializeBuiltInTemplates(): Promise>; /** * Clears the cached built-in templates. * Primarily for testing purposes. */ declare function clearTemplateCache(): void; /** * Creates a WorkflowEngine with real dependencies. * * @param config - Engine configuration * @returns WorkflowEngine instance */ declare function createRealWorkflowEngine(config?: WorkflowEngineFactoryConfig): IWorkflowEngine; /** * Creates and initializes a WorkflowEngine with built-in templates loaded. * This is the recommended way to create a production workflow engine. * * Note: Requires modelAdapter, expertFactory, or useMockExecutor: true to be specified. * Without these, WorkflowExecutionUnavailableError will be thrown. * (Source: Issue #507 - Fail-safe workflow execution) * * @param config - Engine configuration * @returns Promise resolving to WorkflowEngine instance */ declare function createInitializedWorkflowEngine(config?: WorkflowEngineFactoryConfig): Promise; /** * Creates WorkflowEngineDeps asynchronously with auto-detected model adapter. * * This function attempts to auto-detect an available model adapter (CLI or API) * and configures the workflow engine to use the real StepExecutor with ExpertFactory. * Use this when you want production-ready workflow execution with real agent experts. * * @param config - Factory configuration (modelAdapter will be auto-detected if not provided) * @returns Promise resolving to WorkflowEngineDeps * * @example * ```typescript * // Auto-detect adapter and create deps with real execution * const deps = await createWorkflowEngineDepsAsync(); * const engine = new WorkflowEngine(deps); * * // Or with custom config * const deps = await createWorkflowEngineDepsAsync({ * logger: customLogger, * useMockExecutor: false, * }); * ``` */ declare function createWorkflowEngineDepsAsync(config?: WorkflowEngineFactoryConfig): Promise; /** * Creates and initializes a WorkflowEngine with auto-detected model adapter. * * This is the most complete factory function - it: * 1. Loads built-in templates * 2. Auto-detects the best available model adapter (CLI or API) * 3. Creates the workflow engine with real step execution * * Falls back gracefully to mock execution if no adapter is available. * * @param config - Engine configuration * @returns Promise resolving to WorkflowEngine instance * * @example * ```typescript * // Create production-ready workflow engine * const engine = await createProductionWorkflowEngine(); * * // Execute a workflow with real agent experts * const result = await engine.execute(workflow, inputs); * ``` */ declare function createProductionWorkflowEngine(config?: WorkflowEngineFactoryConfig): Promise; /** * nexus-agents/mcp - MCP Server * * Main MCP server implementation for Nexus Agents orchestration. * Provides factory functions to create and start the server with * stdio or custom transports. * * (Source: MCP Protocol 2025-11-25) */ /** * Server configuration options. */ interface ServerConfig { /** Server name (default: "nexus-agents") */ readonly name?: string; /** Server version (default: package version) */ readonly version?: string; /** Logger instance */ readonly logger?: ILogger; } /** * Server creation result containing the server and logger. */ interface ServerInstance { /** The MCP server instance */ readonly server: McpServer; /** The logger instance for this server */ readonly logger: ILogger; } /** * Error type for server operations. */ interface ServerError { code: 'SERVER_CREATION_FAILED' | 'SERVER_START_FAILED' | 'SERVER_STOP_FAILED'; message: string; cause?: Error; } /** * Creates a new MCP server instance. * * @param config - Optional server configuration * @returns Result containing the server instance or an error * * @example * ```typescript * const result = createServer({ name: 'my-server' }); * if (result.ok) { * const { server, logger } = result.value; * // Register tools on server * } * ``` */ declare function createServer(config?: ServerConfig): Result; /** * Connects the server to a transport. * * @param server - The MCP server instance * @param transport - The transport to connect to * @param logger - Logger for the operation * @returns Result indicating success or failure */ declare function connectTransport(server: McpServer, transport: Transport, logger?: ILogger): Promise>; /** * Starts the MCP server with stdio transport. * * This is the main entry point for running the server as a standalone process. * The server will communicate over stdin/stdout using the MCP protocol. * * @param config - Optional server configuration * @returns Result indicating success or failure * * @example * ```typescript * const result = await startStdioServer(); * if (!result.ok) { * console.error('Failed to start server:', result.error.message); * process.exit(1); * } * ``` */ declare function startStdioServer(config?: ServerConfig): Promise>; /** * Gracefully closes the server connection. * * @param server - The MCP server to close * @param logger - Optional logger * @returns Result indicating success or failure */ declare function closeServer(server: McpServer, logger?: ILogger): Promise>; /** * nexus-agents/mcp - Validation Middleware * * Input validation helper using Zod schemas. * All tool inputs must be validated at the boundary. * * (Source: MCP Protocol 2025-11-25, Zod Documentation) */ /** * Validates tool input against a Zod schema. * * This function should be called at the start of every tool handler * to validate incoming arguments before processing. * * @template T - The expected type after validation * @param schema - The Zod schema to validate against * @param args - The unknown input to validate * @returns Result containing validated data or a ValidationError * * @example * ```typescript * const InputSchema = z.object({ * task: z.string().min(1), * context: z.record(z.string(), z.unknown()).optional(), * }); * * server.tool('my_tool', InputSchema.shape, async (args) => { * const result = validateToolInput(InputSchema, args); * if (!result.ok) { * return toolStructuredError({ errorCategory: 'validation', message: result.error.message }); * } * const { task, context } = result.value; * // Process validated input... * }); * ``` */ declare function validateToolInput(schema: ZodType, args: unknown): Result; /** * Creates a validation function bound to a specific schema. * * Useful for reusing the same schema across multiple tools. * * @template T - The expected type after validation * @param schema - The Zod schema to bind * @returns A validation function for the schema * * @example * ```typescript * const validateTask = createValidator(TaskSchema); * * // Later in tool handlers: * const result = validateTask(args); * ``` */ declare function createValidator(schema: ZodType): (args: unknown) => Result; /** * nexus-agents/mcp - Logging Middleware * * Structured logger context for MCP operations. * Provides consistent logging across all MCP tools and handlers. */ /** * MCP-specific log context fields. */ interface McpLogContext extends LogContext { /** The tool being executed */ tool?: string; /** Request ID for tracing */ requestId?: string; /** Duration of the operation in milliseconds */ durationMs?: number; /** Whether the operation succeeded */ success?: boolean; /** Error code if operation failed */ errorCode?: string; } /** * Creates a logger with MCP-specific context. * * @param baseContext - Base context to include in all log entries * @returns An ILogger instance with MCP context * * @example * ```typescript * const logger = createMcpLogger({ requestId: 'req-123' }); * logger.info('Processing request', { tool: 'orchestrate' }); * ``` */ declare function createMcpLogger(baseContext?: McpLogContext): ILogger; /** * Creates a child logger for a specific tool execution. * * @param parentLogger - The parent logger instance * @param toolName - Name of the tool being executed * @param requestId - Optional request ID for tracing * @returns A child logger with tool context */ declare function createToolLogger(parentLogger: ILogger, toolName: string, requestId?: string): ILogger; /** * Logs the start of a tool execution. * * @param logger - The logger to use * @param toolName - Name of the tool * @param args - Tool arguments (sanitized for logging) */ declare function logToolStart(logger: ILogger, toolName: string, args?: Record): void; /** * Logs the successful completion of a tool execution. * * @param logger - The logger to use * @param toolName - Name of the tool * @param durationMs - Duration of the execution in milliseconds * @param resultInfo - Optional information about the result */ declare function logToolSuccess(logger: ILogger, toolName: string, durationMs: number, resultInfo?: Record): void; /** * Logs a failed tool execution. * * @param logger - The logger to use * @param toolName - Name of the tool * @param error - The error that occurred * @param durationMs - Duration of the execution in milliseconds */ declare function logToolError(logger: ILogger, toolName: string, error: Error, durationMs: number): void; /** * Creates a timing utility for measuring operation duration. * * @returns An object with start time and elapsed() method * * @example * ```typescript * const timer = createTimer(); * // ... perform operation * const durationMs = timer.elapsed(); * ``` */ declare function createTimer(): { elapsed: () => number; }; /** * Higher-order function that wraps a tool handler with logging. * * @template TArgs - Tool argument type * @template TResult - Tool result type * @param toolName - Name of the tool * @param handler - The tool handler function * @param logger - The logger to use * @returns A wrapped handler with automatic logging * * @example * ```typescript * const wrappedHandler = withLogging( * 'my_tool', * async (args) => { ... }, * logger * ); * ``` */ declare function withLogging(toolName: string, handler: (args: TArgs) => Promise, logger: ILogger): (args: TArgs) => Promise; /** * nexus-agents/mcp - Policy Firewall Types * * Type definitions for the authorization layer of MCP tool calls. * * (Source: OWASP ASVS 4.0, Authorization Controls) */ /** * Artifact type for policy context. * Artifacts are resources that can be referenced in policy decisions. */ interface Artifact$1 { readonly id: string; readonly type: string; readonly value: T; readonly createdAt: Date; } /** * Execution mode for tool operations. * - 'read-only': Only read operations allowed (default) * - 'read-write': Both read and write operations allowed */ type ExecutionMode = 'read-only' | 'read-write'; /** * Policy enforcement mode. * - 'enforce': Block denied operations * - 'warn': Log denials but allow execution (for migration) */ type PolicyMode$1 = 'enforce' | 'warn'; /** * Result of a policy evaluation. */ interface PolicyDecision$2 { readonly allowed: boolean; readonly reason: string; readonly requiredArtifact?: string; readonly ruleName?: string; /** * A rule denied this call and warn mode overrode the denial, so `allowed` is * `true` but the operation WOULD have been blocked in enforce mode (#4991). * * Set explicitly by the evaluator rather than inferred downstream. The first * implementation deduced it from `allowed === true && ruleName !== undefined` * — true of today's code, because `allowWithReason` never sets `ruleName` — * and a consensus panel rejected that: naming which rule *permitted* an * action (`admin-override` vs `default-allow`) is ordinary access-control * practice, so the day an allow rule sets `ruleName`, every authorized call * it covers would be silently recorded as a near-miss. Deriving a verdict * from the absence of an unrelated field is not a signal, it is a * coincidence. */ readonly overriddenByWarnMode?: boolean; } /** * Context provided to policy rules for evaluation. */ interface PolicyContext$1 { readonly toolName: string; readonly args: unknown; readonly mode: ExecutionMode; readonly artifacts?: Map; readonly workflowId?: string; readonly allowedPaths?: readonly string[]; } /** * A single policy rule that can approve or deny operations. */ interface PolicyRule$1 { readonly name: string; readonly description: string; check(ctx: PolicyContext$1): PolicyDecision$2; } /** * Interface for the policy firewall. */ interface IPolicyFirewall { evaluate(ctx: PolicyContext$1): PolicyDecision$2; addRule(rule: PolicyRule$1): void; removeRule(name: string): boolean; getRules(): readonly PolicyRule$1[]; setMode(mode: PolicyMode$1): void; getMode(): PolicyMode$1; } /** * Configuration for the policy firewall. */ interface PolicyFirewallConfig { /** Enforcement mode (default: 'enforce') */ readonly mode?: PolicyMode$1; /** Logger instance */ readonly logger?: ILogger; /** Initial rules to register */ readonly rules?: readonly PolicyRule$1[]; } /** * Policy error for authorization failures. */ declare class PolicyError extends SecurityError { readonly decision: PolicyDecision$2; constructor(message: string, decision: PolicyDecision$2); } /** * Schema for policy configuration. */ declare const PolicyConfigSchema: z.ZodObject<{ defaultMode: z.ZodDefault>; policyMode: z.ZodDefault>; allowedPaths: z.ZodDefault>; }, z.core.$strip>; type PolicyConfig = z.infer; /** * nexus-agents/mcp - Policy Firewall Rules * * Default policy rules and constants for the authorization layer. * * (Source: OWASP ASVS 4.0, Authorization Controls) */ /** * Policy rule that denies mutation operations when mode is 'read-only'. * * This ensures that write operations are only allowed when explicitly * enabled via the 'read-write' mode. Two inputs: `ctx.mode` is the permission * the operator granted; the tool's class comes from the manifest (#5114). An * unclassified tool is denied too, but the verdict SAYS it was unclassified — * a rollout needs to tell "a write the mode forbids" from "nobody classified * this", and a boolean cannot. */ declare const denyMutationsWithoutModeRule: PolicyRule$1; /** * Policy rule that validates paths against allowed roots. * * Prevents path traversal attacks by ensuring all file operations * target paths within configured allowed directories. */ declare const safePathsRule: PolicyRule$1; /** * Policy rule that denies access to secret-bearing paths (SSH keys, cloud * credentials, `.env`, `/etc/shadow`, …) whatever `allowedPaths` says. * * Composes AND-deny with {@link safePathsRule}: that rule is containment * against the allowlist, this one is a denylist inside it. A caller who widens * `allowedPaths` to `$HOME` keeps `~/.ssh` closed, and `.env` inside the repo * root is refused even though it passes containment. No path argument → the * rule abstains (an allow with that reason), because absence of a path is not * a file operation and must not be recorded as "no secret". */ declare const secretPathsRule: PolicyRule$1; /** * nexus-agents/mcp - Policy Firewall Middleware * * Authorization layer for MCP tool calls. Evaluates policy rules * to determine whether operations should be allowed or denied. * * This is separate from validation - validation checks if input is well-formed, * policy checks if the operation is authorized. * * (Source: OWASP ASVS 4.0, Authorization Controls) */ /** * Policy firewall that evaluates rules to authorize or deny operations. * * Rules are evaluated in order. The first rule that denies the operation * stops evaluation and returns the denial. If all rules pass, the operation * is allowed. * * @example * ```typescript * const firewall = new PolicyFirewall({ mode: 'enforce' }); * * // Add rules * firewall.addRule(denyMutationsWithoutModeRule); * firewall.addRule(safePathsRule); * * // Evaluate * const decision = firewall.evaluate({ * toolName: 'write_file', * args: { path: '/etc/passwd' }, * mode: 'read-only', * }); * * if (!decision.allowed) { * console.error(`Denied: ${decision.reason}`); * } * ``` */ declare class PolicyFirewall implements IPolicyFirewall { private readonly rules; private mode; private readonly logger; constructor(config?: PolicyFirewallConfig); /** * Evaluates all policy rules against the given context. * * Rules are evaluated in order. The first rule that denies stops * evaluation and returns the denial decision. * * @param ctx - The policy context to evaluate * @returns The policy decision */ evaluate(ctx: PolicyContext$1): PolicyDecision$2; /** * Creates an allow decision with the given reason and logs it. */ private allowWithReason; /** * Handles a rule denial, respecting warn mode if configured. */ private handleDenial; /** * Adds a policy rule to the firewall. * * @param rule - The rule to add */ addRule(rule: PolicyRule$1): void; /** * Removes a policy rule by name. * * @param name - The name of the rule to remove * @returns True if the rule was found and removed */ removeRule(name: string): boolean; /** * Gets all registered policy rules. * * @returns A readonly array of policy rules */ getRules(): readonly PolicyRule$1[]; /** * Sets the policy enforcement mode. * * @param mode - The new enforcement mode */ setMode(mode: PolicyMode$1): void; /** * Gets the current policy enforcement mode. * * @returns The current mode */ getMode(): PolicyMode$1; /** * Logs a policy decision for audit purposes. */ private logDecision; } /** * Creates a policy firewall with default rules. * * Default rules included, in evaluation order: * - deny-mutations-without-mode * - secret-paths (#5108) — ahead of safe-paths so a secret is reported as a * secret, not as a `..` or an out-of-root path * - safe-paths * * @param config - Optional configuration * @returns A configured PolicyFirewall instance */ declare function createDefaultPolicyFirewall(config?: PolicyFirewallConfig): PolicyFirewall; /** * Evaluates a policy context and returns a Result. * * This is a convenience function that wraps the firewall evaluation * in a Result type for easier error handling. * * @param firewall - The policy firewall to use * @param ctx - The policy context to evaluate * @returns Result containing void on success or PolicyError on denial */ declare function evaluatePolicy$1(firewall: IPolicyFirewall, ctx: PolicyContext$1): Result; /** * Creates a policy context from tool invocation parameters. * * @param toolName - Name of the tool being invoked * @param args - Tool arguments * @param options - Additional context options * @returns A PolicyContext object */ declare function createPolicyContext(toolName: string, args: unknown, options?: { mode?: ExecutionMode; artifacts?: Map; workflowId?: string; allowedPaths?: readonly string[]; }): PolicyContext$1; /** * nexus-agents/security - Trust Types * * Zod schemas and TypeScript types for the untrusted input hardening * framework. Defines trust tiers, sanitized input, user roles, and * injection detection flags. * * @module security/trust-types * (Source: Issue #818, #819 — Phase 1: Input Sanitization) */ /** * Trust tier classification for input sources. * Lower number = higher trust. * * 1 = Authoritative (repo files, CI, CLAUDE.md, allowlisted maintainers) * 2 = Semi-trusted (collaborator issue body, contributor PR metadata) * 3 = Untrusted (unknown user comments, non-collaborator issue body) * 4 = Hostile (injection patterns, hidden HTML, instruction-like content) */ declare const TrustTierSchema: z.ZodEnum<{ 1: "1"; 2: "2"; 3: "3"; 4: "4"; }>; type TrustTier = z.infer; /** Numeric trust tier for comparisons. Higher number = lower trust. */ declare const TRUST_TIER_NUMERIC: Record; /** * GitHub user relationship to the repository. */ declare const GitHubUserRoleSchema: z.ZodEnum<{ unknown: "unknown"; owner: "owner"; maintainer: "maintainer"; collaborator: "collaborator"; contributor: "contributor"; member: "member"; }>; type GitHubUserRole = z.infer; /** * Default trust tier mapping for each GitHub role. * Can be overridden by injection pattern detection (downgrade only). */ declare const ROLE_DEFAULT_TRUST: Record; /** * Categories of injection patterns detected in content. */ declare const InjectionFlagSchema: z.ZodEnum<{ authority_claim: "authority_claim"; instruction_pattern: "instruction_pattern"; system_prompt_manipulation: "system_prompt_manipulation"; hidden_content: "hidden_content"; urgency_manipulation: "urgency_manipulation"; fake_conversation: "fake_conversation"; base64_encoded: "base64_encoded"; external_link_instruction: "external_link_instruction"; }>; type InjectionFlag = z.infer; /** * An element stripped during sanitization, preserved for audit trail. */ declare const StrippedElementSchema: z.ZodObject<{ tag: z.ZodString; reason: z.ZodString; startIndex: z.ZodNumber; length: z.ZodNumber; }, z.core.$strip>; type StrippedElement = z.infer; /** * The result of sanitizing untrusted input. * Contains cleaned content, trust classification, and audit data. */ declare const SanitizedInputSchema: z.ZodObject<{ content: z.ZodString; originalLength: z.ZodNumber; trustTier: z.ZodEnum<{ 1: "1"; 2: "2"; 3: "3"; 4: "4"; }>; contentTierMeasured: z.ZodOptional; userRole: z.ZodEnum<{ unknown: "unknown"; owner: "owner"; maintainer: "maintainer"; collaborator: "collaborator"; contributor: "contributor"; member: "member"; }>; injectionFlags: z.ZodArray>; strippedElements: z.ZodArray>; truncated: z.ZodOptional; wasModified: z.ZodBoolean; sanitizationIncomplete: z.ZodOptional; sanitizedAt: z.ZodISODateTime; }, z.core.$strip>; type SanitizedInput = z.infer; /** * Configuration for the input sanitizer. */ declare const SanitizerConfigSchema: z.ZodObject<{ allowlistedMaintainers: z.ZodDefault>; failOpen: z.ZodDefault; maxInputLength: z.ZodDefault; }, z.core.$strip>; type SanitizerConfig = z.infer; /** * nexus-agents/mcp - Request Context Middleware * * Provides request ID generation and caller context tracking for MCP tools. * (Source: Issue #185 Phase 1 - Request context & PolicyFirewall integration) * * @module mcp/middleware/request-context */ /** * Authenticated user information. * (Source: Issue #739 - MCP authentication) */ interface AuthenticatedUser { /** Unique user/client identifier */ readonly id: string; /** Human-readable name (optional) */ readonly name?: string; /** Granted permissions/scopes (optional) */ readonly permissions?: readonly string[]; } /** * Caller identification for audit trails. */ interface CallerInfo { /** Client identifier (e.g., 'claude-cli', 'gemini-cli') */ readonly clientId?: string; /** User agent string if available */ readonly userAgent?: string; /** Session ID for request correlation */ readonly sessionId?: string; /** IP address or transport identifier */ readonly transport?: string; /** Whether the request is authenticated (Issue #739) */ readonly authenticated?: boolean; /** Authenticated user information (Issue #739) */ readonly authenticatedUser?: AuthenticatedUser; } /** * Request context for MCP tool invocations. * Immutable once created. */ interface RequestContext { /** Unique request identifier (format: req_<16 hex chars>) */ readonly requestId: string; /** Timestamp when request was received (ISO 8601, ET) */ readonly timestamp: string; /** Tool being invoked */ readonly toolName: string; /** Caller information for audit */ readonly caller: CallerInfo; /** * Trust tier for this request (Issue #828). * Derived from caller authentication state: * - '1' = Authenticated + known client, or stdio (local-only) * - '2' = Authenticated via network * - '3' = Unauthenticated network request * - '4' = Request with detected injection patterns (set by sanitizer) */ readonly trustTier: TrustTier; /** Trace ID for distributed tracing correlation */ readonly traceId?: string; /** Parent span ID if part of a larger trace */ readonly parentSpanId?: string; } /** * nexus-agents/audit - Audit Event Types * * Zod schemas and TypeScript types for structured audit logging. * SIEM-compatible format with cryptographic integrity support. * * (Source: Issue #193 - Phase 3 structured audit logging) * * @module audit/audit-types */ declare class AuditError extends Error { readonly code = "AUDIT_ERROR"; readonly context: Record | undefined; readonly cause: Error | undefined; constructor(message: string, options?: { cause?: Error; context?: Record; }); } declare const AuditCategorySchema: z.ZodEnum<{ authorization: "authorization"; system: "system"; configuration: "configuration"; security: "security"; governance: "governance"; authentication: "authentication"; tool_invocation: "tool_invocation"; data_access: "data_access"; data_modification: "data_modification"; }>; type AuditCategory = z.infer; /** * The two directions a loop can move on the authority ladder (ADR-0017 * §"Transition Rules"). A `promotion` moves UP a tier and is invalid without a * linked ratification vote; a `demotion` moves DOWN and is automatic (needs no * vote). The ratification gate (`scripts/check-authority-tier-drift.ts`) keys * off this kind: a `promotion` event lacking `ratificationVoteRef` FAILS the * gate, a `demotion` does not. */ declare const TierTransitionKindSchema: z.ZodEnum<{ promotion: "promotion"; demotion: "demotion"; }>; type TierTransitionKind = z.infer; /** * The authority tier vocabulary, mirrored from * `orchestration/strategy-manifest.ts` `AuthorityTierSchema`. Declared here so * the audit module has no dependency on the orchestration layer (the audit log * is the lower layer). A drift between the two enums is caught by the audit * tier-transition tests, which round-trip every tier through the emitter. */ declare const TierTransitionTierSchema: z.ZodEnum<{ enforce: "enforce"; observe: "observe"; suggest: "suggest"; advisory: "advisory"; }>; type TierTransitionTier = z.infer; /** * Options for {@link IAuditLogger.logTierTransition}. The `actor` defaults to the * system actor at the emission site when omitted (a tier change recorded by the * evidence ledger is a system event). */ interface TierTransitionAuditOpts { kind: TierTransitionKind; subject: string; fromTier: TierTransitionTier; toTier: TierTransitionTier; evidenceRef: string; ratificationVoteRef?: string | undefined; actor?: AuditActor | undefined; requestId?: string | undefined; metadata?: Record | undefined; } declare const AuditSeveritySchema: z.ZodEnum<{ info: "info"; warning: "warning"; critical: "critical"; }>; type AuditSeverity = z.infer; declare const AuditOutcomeSchema: z.ZodEnum<{ error: "error"; success: "success"; failure: "failure"; denied: "denied"; }>; type AuditOutcome = z.infer; declare const AuditActorSchema: z.ZodObject<{ type: z.ZodEnum<{ system: "system"; user: "user"; external: "external"; agent: "agent"; }>; id: z.ZodString; name: z.ZodOptional; ip: z.ZodOptional; userAgent: z.ZodOptional; }, z.core.$strip>; type AuditActor = z.infer; declare const AuditResourceSchema: z.ZodObject<{ type: z.ZodString; id: z.ZodString; name: z.ZodOptional; path: z.ZodOptional; }, z.core.$strip>; type AuditResource = z.infer; declare const AuditEventSchema: z.ZodObject<{ id: z.ZodString; version: z.ZodLiteral<"1.0">; timestamp: z.ZodString; timestampMs: z.ZodNumber; category: z.ZodEnum<{ authorization: "authorization"; system: "system"; configuration: "configuration"; security: "security"; governance: "governance"; authentication: "authentication"; tool_invocation: "tool_invocation"; data_access: "data_access"; data_modification: "data_modification"; }>; severity: z.ZodEnum<{ info: "info"; warning: "warning"; critical: "critical"; }>; outcome: z.ZodEnum<{ error: "error"; success: "success"; failure: "failure"; denied: "denied"; }>; action: z.ZodString; description: z.ZodOptional; actor: z.ZodObject<{ type: z.ZodEnum<{ system: "system"; user: "user"; external: "external"; agent: "agent"; }>; id: z.ZodString; name: z.ZodOptional; ip: z.ZodOptional; userAgent: z.ZodOptional; }, z.core.$strip>; resource: z.ZodOptional; path: z.ZodOptional; }, z.core.$strip>>; requestId: z.ZodOptional; traceId: z.ZodOptional; sessionId: z.ZodOptional; toolName: z.ZodOptional; durationMs: z.ZodOptional; metadata: z.ZodOptional>; policyName: z.ZodOptional; policyDecision: z.ZodOptional; policyOccurrence: z.ZodOptional; violationType: z.ZodOptional; previousHash: z.ZodOptional; hash: z.ZodOptional; hashVersion: z.ZodOptional; }, z.core.$strip>; type AuditEvent$1 = z.infer; declare const AuditEventInputSchema: z.ZodObject<{ category: z.ZodEnum<{ authorization: "authorization"; system: "system"; configuration: "configuration"; security: "security"; governance: "governance"; authentication: "authentication"; tool_invocation: "tool_invocation"; data_access: "data_access"; data_modification: "data_modification"; }>; severity: z.ZodDefault>>; outcome: z.ZodEnum<{ error: "error"; success: "success"; failure: "failure"; denied: "denied"; }>; action: z.ZodString; description: z.ZodOptional; actor: z.ZodObject<{ type: z.ZodEnum<{ system: "system"; user: "user"; external: "external"; agent: "agent"; }>; id: z.ZodString; name: z.ZodOptional; ip: z.ZodOptional; userAgent: z.ZodOptional; }, z.core.$strip>; resource: z.ZodOptional; path: z.ZodOptional; }, z.core.$strip>>; requestId: z.ZodOptional; traceId: z.ZodOptional; sessionId: z.ZodOptional; toolName: z.ZodOptional; durationMs: z.ZodOptional; metadata: z.ZodOptional>; policyName: z.ZodOptional; policyDecision: z.ZodOptional; policyOccurrence: z.ZodOptional; violationType: z.ZodOptional; }, z.core.$strip>; type AuditEventInput = z.infer; declare const AuditLogConfigSchema: z.ZodObject<{ logDir: z.ZodString; filePrefix: z.ZodDefault>; maxFileSizeBytes: z.ZodDefault>; maxFiles: z.ZodDefault>; enableHashChain: z.ZodDefault>; enableCompression: z.ZodDefault>; flushIntervalMs: z.ZodDefault>; maxQueueDepth: z.ZodDefault>; minSeverity: z.ZodDefault>>; categories: z.ZodOptional>>; }, z.core.$strip>; type AuditLogConfig = z.infer; interface IAuditStorage { /** Write an audit event to storage */ write: (event: AuditEvent$1) => Promise; /** Flush pending writes */ flush: () => Promise; /** Close the storage */ close: () => Promise; /** Query events by criteria */ query: (criteria: AuditQueryCriteria) => Promise; } declare const AuditQueryCriteriaSchema: z.ZodObject<{ startTime: z.ZodOptional; endTime: z.ZodOptional; categories: z.ZodOptional>>; severities: z.ZodOptional>>; outcomes: z.ZodOptional>>; actorId: z.ZodOptional; resourceId: z.ZodOptional; requestId: z.ZodOptional; traceId: z.ZodOptional; limit: z.ZodDefault>; offset: z.ZodDefault>; }, z.core.$strip>; type AuditQueryCriteria = z.infer; /** * Sink for audit records. * * **Every member is declared as a function PROPERTY, not a method, and that is * load-bearing (#4991.)** TypeScript exempts method-shorthand parameters from * `strictFunctionTypes` and checks them bivariantly. When * {@link PolicyAuditDecision} gained `would_deny`, an out-of-tree implementor * still typed against the old two-value union would have kept COMPILING and * then received a value it cannot handle at runtime — silently dropping the * audit record, or throwing inside the authorization path. A major version bump * is a note in a changelog; a property signature is a compile error. * * EVERY member is converted, not just the one whose union widened. (Stated * without a count on purpose: a literal here drifts the moment a member is * added, which is the same doc-accuracy defect this file is fixing elsewhere. * `audit-types-variance.test.ts` asserts the property, whatever the count.) An * earlier revision converted only `logPolicyDecision`, on the reasoning that * touching the others "would break implementors for no reason". That reasoning * was wrong, and a panel caught it: an ES6 class using ordinary method syntax * satisfies a property signature perfectly well, as does an object literal with * method shorthand — the ONLY implementor a property signature rejects is one * whose parameter is *narrower* than declared, which is exactly the unsound * case. Converting one member and leaving six is the dangerous state: it looks * consistent enough to imitate, and the next person to widen a parameter on any * of the other six silently reopens the same hole. * * **Limit, stated because it is real:** contravariant checking requires * `strictFunctionTypes` (implied by `strict`) in the CONSUMER's tsconfig. A * downstream project compiling without it falls back to bivariance, compiles a * stale implementor, and drops `would_deny` records at runtime. That flag is * outside this package's control, so the guarantee here is "strict consumers * get a compile error", not "no consumer can get this wrong". * * Pinned by `audit-types-variance.test.ts`, whose `@ts-expect-error` probe * fails with TS2578 if any of these reverts to method shorthand. */ interface IAuditLogger { /** Log an audit event */ log: (input: AuditEventInput) => void; /** Log a tool invocation */ logToolInvocation: (opts: ToolInvocationAuditOpts) => void; /** Log a policy decision. See the interface note on parameter variance. */ logPolicyDecision: (opts: PolicyDecisionAuditOpts) => void; /** Log a security event */ logSecurityEvent: (opts: SecurityEventAuditOpts) => void; /** Log a rate limit violation */ logRateLimitViolation: (opts: RateLimitAuditOpts) => void; /** Log an authority-tier transition (promotion/demotion) — Epic D, #3842. */ logTierTransition: (opts: TierTransitionAuditOpts) => void; /** Flush pending events */ flush: () => Promise; /** Close the logger */ close: () => Promise; } interface ToolInvocationAuditOpts { toolName: string; outcome: AuditOutcome; actor: AuditActor; requestId?: string | undefined; durationMs?: number | undefined; errorMessage?: string | undefined; metadata?: Record | undefined; /** * The policy verdict for this invocation, when a rule fired (#5228 review). * * Only `would_deny` reaches here: a real `deny` returns before the handler * runs, so it produces no invocation record at all. Set on EVERY near-miss * invocation, including those whose separate policy record was sampled out — * otherwise an executed near-miss would be indistinguishable from a call no * rule touched, which is the inference this change exists to break. */ policyDecision?: PolicyAuditDecision | undefined; } /** * The verdict a policy evaluation reached. * * `would_deny` (#4991) is warn mode: a rule fired, but the firewall allowed the * call anyway. It is deliberately NOT `deny` — recording it as a denial would * assert an enforcement that never happened — and NOT `allow`, which would * erase the only signal the warn-mode soak produces. `#4988`'s enforce decision * is read from these records, so the instrument has to be able to say * "a rule would have stopped this" without lying in either direction. * * BREAKING for implementors of {@link IAuditLogger} (ratified 5/6, #4991): * TypeScript's method-parameter bivariance means an out-of-tree implementor * typed against the old two-value union still COMPILES and then receives * `would_deny` at runtime, falling through whatever its `=== 'deny'` branch * does. The major version bump is the only thing that makes those implementors * look. */ type PolicyAuditDecision = 'allow' | 'deny' | 'would_deny'; interface PolicyDecisionAuditOpts { policyName: string; decision: PolicyAuditDecision; reason: string; toolName: string; actor: AuditActor; requestId?: string | undefined; metadata?: Record | undefined; /** * Which occurrence of this `{tool, rule}` near-miss this record represents * (#5228 review). Set only for a sampled `would_deny`; absent means every * occurrence was recorded. */ occurrence?: number | undefined; } interface SecurityEventAuditOpts { eventType: string; severity: AuditSeverity; actor: AuditActor; description: string; requestId?: string | undefined; metadata?: Record | undefined; } interface RateLimitAuditOpts { toolName: string; actor: AuditActor; currentRate: number; limitRate: number; requestId?: string | undefined; } /** * nexus-agents/mcp - MCP Notification Helper * * Sends structured logging notifications to MCP clients via * the `notifications/message` protocol method. * Clients (e.g., Claude Code) can display these for real-time * observability of orchestration events. * * Also provides progress notification support via AsyncLocalStorage * for resetting client-side request timeouts (MCP SDK resetTimeoutOnProgress). * * @module mcp/mcp-notifier * (Source: Issue #973, #974 — Claude Code Observability) * (Source: Issue #1108 — Progress heartbeat timeout reset) * (Source: MCP Protocol 2025-11-25, Logging Specification) */ /** * Logging levels for MCP notifications (RFC 5424 syslog). */ type McpLogLevel = 'debug' | 'info' | 'notice' | 'warning' | 'error'; /** * MCP notifier for sending structured log events to clients. */ interface IMcpNotifier { /** Send info-level notification (key orchestration events) */ info(logger: string, data: Record): void; /** Send debug-level notification (detailed execution steps) */ debug(logger: string, data: Record): void; /** Send warning-level notification */ warn(logger: string, data: Record): void; } /** * Creates an MCP notifier that sends logging notifications to connected clients. * * Notifications are fire-and-forget — failures are logged but never * propagate to callers. This ensures observability never breaks tool execution. */ declare function createMcpNotifier(server: McpServer): IMcpNotifier; /** * No-op notifier for when MCP server is not available. */ declare const NOOP_NOTIFIER: IMcpNotifier; /** * nexus-agents/observability - SwarmObserver Core Types * * Primitive type definitions for swarm observer. * Extracted to break circular dependency between swarm-observer-types, * swarm-observer-payloads, and swarm-observer-schemas. * * @module observability/swarm-observer-core-types * (Source: Issue #392 - Circular dependency resolution) */ /** * Unique identifier for agents in the swarm. */ type AgentId = string; /** * Unique identifier for tasks. */ type TaskId = string; /** * OpenTelemetry-compatible trace identifier. * Format: 32-character hex string (128-bit). */ type TraceId = string; /** * OpenTelemetry-compatible span identifier. * Format: 16-character hex string (64-bit). */ type SpanId = string; /** * Types of events the observer can track. */ type EventType = 'state_change' | 'message_sent' | 'message_received' | 'tool_invoked' | 'tool_completed' | 'memory_read' | 'memory_write' | 'task_started' | 'task_completed' | 'error'; /** * Agent state for tracking state transitions. */ type AgentState = 'idle' | 'thinking' | 'executing' | 'waiting' | 'error'; /** * Outcome of an interaction. */ type InteractionOutcome = 'success' | 'failure' | 'timeout' | 'pending'; /** * Configuration for the SwarmObserver. */ interface SwarmObserverConfig { /** Maximum events to keep in memory */ readonly maxEvents: number; /** Time window for metrics calculation (ms) */ readonly metricsWindowMs: number; /** Enable detailed payload logging */ readonly logPayloads: boolean; /** Bottleneck threshold (queued messages) */ readonly bottleneckThreshold: number; /** Minimum cluster size to detect */ readonly minClusterSize: number; /** Cohesion threshold for cluster detection */ readonly cohesionThreshold: number; } /** * nexus-agents/observability - SwarmObserver Zod Schemas * * Zod validation schemas for swarm observer types. * Extracted from swarm-observer-types.ts for file size compliance. * * @module observability/swarm-observer-schemas * (Source: Alignment Roadmap Phase 1, Issue #158) */ /** * Default configuration for SwarmObserver. */ declare const DEFAULT_SWARM_OBSERVER_CONFIG: SwarmObserverConfig; /** * Zod schema for SwarmObserverConfig validation. */ declare const SwarmObserverConfigSchema: z.ZodObject<{ maxEvents: z.ZodDefault; metricsWindowMs: z.ZodDefault; logPayloads: z.ZodDefault; bottleneckThreshold: z.ZodDefault; minClusterSize: z.ZodDefault; cohesionThreshold: z.ZodDefault; }, z.core.$strip>; /** * Zod schema for AgentEvent validation. */ declare const AgentEventSchema: z.ZodObject<{ eventId: z.ZodString; timestamp: z.ZodISODateTime; agentId: z.ZodString; eventType: z.ZodEnum<{ error: "error"; memory_write: "memory_write"; state_change: "state_change"; message_sent: "message_sent"; message_received: "message_received"; tool_invoked: "tool_invoked"; tool_completed: "tool_completed"; memory_read: "memory_read"; task_started: "task_started"; task_completed: "task_completed"; }>; traceId: z.ZodString; spanId: z.ZodString; parentSpanId: z.ZodOptional; payload: z.ZodRecord; durationMs: z.ZodOptional; }, z.core.$strip>; /** * nexus-agents/observability - SwarmObserver Event Payloads * * Event payload type definitions for swarm observer events. * Extracted from swarm-observer-types.ts for file size compliance. * * @module observability/swarm-observer-payloads * (Source: Alignment Roadmap Phase 1, Issue #158) */ /** * Discriminated union of event payloads. */ type EventPayload = StateChangePayload | MessagePayload | ToolPayload | MemoryPayload | TaskPayload | ErrorPayload; /** * Payload for state change events. */ interface StateChangePayload { readonly type: 'state_change'; readonly previousState: AgentState; readonly newState: AgentState; readonly reason?: string; } /** * Payload for message events. */ interface MessagePayload { readonly type: 'message'; readonly direction: 'sent' | 'received'; readonly targetAgentId?: AgentId; readonly sourceAgentId?: AgentId; readonly messageType: string; /** Truncated preview of message content */ readonly contentPreview?: string; } /** * Payload for tool invocation events. */ interface ToolPayload { readonly type: 'tool'; readonly phase: 'invoked' | 'completed'; readonly toolName: string; readonly success?: boolean; readonly errorMessage?: string; } /** * Payload for memory operation events. */ interface MemoryPayload { readonly type: 'memory'; readonly operation: 'read' | 'write'; readonly memoryType: string; readonly key?: string; readonly sizeBytes?: number; } /** * Payload for task lifecycle events. */ interface TaskPayload { readonly type: 'task'; readonly phase: 'started' | 'completed'; readonly taskId: TaskId; readonly taskDescription?: string; readonly success?: boolean; } /** * Payload for error events. */ interface ErrorPayload { readonly type: 'error'; readonly errorCode: string; readonly errorMessage: string; readonly stack?: string; readonly recoverable: boolean; } /** * nexus-agents/observability - SwarmObserver Types * * Type definitions for swarm-level observability and interaction tracking. * Enables measurement of emergent behavior, bottleneck detection, and * agent collaboration patterns. * * @module observability/swarm-observer-types * (Source: Alignment Roadmap Phase 1, Issue #158) */ /** * Core event emitted by agents for observation. */ interface AgentEvent { /** Event ID for deduplication */ readonly eventId: string; /** ISO timestamp when event occurred */ readonly timestamp: string; /** Agent that emitted the event */ readonly agentId: AgentId; /** Type of event */ readonly eventType: EventType; /** OpenTelemetry trace ID for correlation */ readonly traceId: TraceId; /** OpenTelemetry span ID */ readonly spanId: SpanId; /** Parent span ID for hierarchical tracing */ readonly parentSpanId?: SpanId; /** Event-specific payload */ readonly payload: EventPayload; /** Duration in milliseconds (for completed events) */ readonly durationMs?: number; } /** * Edge in the interaction graph representing a message/interaction. */ interface InteractionEdge { /** Source agent */ readonly from: AgentId; /** Target agent */ readonly to: AgentId; /** Type of interaction */ readonly interactionType: string; /** When interaction occurred */ readonly timestamp: string; /** Outcome of interaction */ readonly outcome: InteractionOutcome; /** Duration if applicable */ readonly durationMs?: number | undefined; /** Trace ID for correlation */ readonly traceId: TraceId; /** Weight for graph algorithms (default 1) */ readonly weight: number; } /** * Options for recording an interaction. */ interface RecordInteractionOptions { /** Source agent */ readonly from: AgentId; /** Target agent */ readonly to: AgentId; /** Type of interaction */ readonly interactionType: string; /** Outcome of interaction */ readonly outcome: InteractionOutcome; /** Trace ID for correlation */ readonly traceId: TraceId; /** Duration in milliseconds */ readonly durationMs?: number | undefined; } /** * Contribution score for a single agent to a task. */ interface ContributionScore { readonly agentId: AgentId; /** Overall contribution score (0-1) */ readonly score: number; /** Number of messages sent */ readonly messagesSent: number; /** Number of messages received */ readonly messagesReceived: number; /** Time spent actively working (ms) */ readonly activeTimeMs: number; /** Number of successful tool invocations */ readonly successfulTools: number; /** Number of errors encountered */ readonly errorCount: number; } /** * Bottleneck information for an agent. */ interface BottleneckInfo { readonly agentId: AgentId; /** Messages waiting to be processed */ readonly queuedMessages: number; /** Average time messages wait */ readonly avgWaitTimeMs: number; /** Number of agents blocked waiting */ readonly blockedAgents: number; /** Severity level */ readonly severity: 'low' | 'medium' | 'high' | 'critical'; } /** * Cluster of agents that work together frequently. */ interface AgentCluster { /** Cluster identifier */ readonly clusterId: string; /** Agents in this cluster */ readonly agents: AgentId[]; /** Cohesion score (0-1, higher = tighter cluster) */ readonly cohesion: number; /** Number of interactions within cluster */ readonly internalInteractions: number; /** Number of interactions with external agents */ readonly externalInteractions: number; /** Dominant interaction pattern */ readonly dominantPattern?: string | undefined; } /** * Swarm-level health metrics. */ interface SwarmHealthMetrics$1 { /** Total agents in swarm */ readonly totalAgents: number; /** Currently active agents */ readonly activeAgents: number; /** Agents in error state */ readonly errorAgents: number; /** Total interactions in time window */ readonly totalInteractions: number; /** Successful interaction rate (0-1) */ readonly successRate: number; /** * Mean latency over the interactions that CARRIED a duration (#5782). * * `durationMs` is optional on a recorded interaction and the server-wide * producer (`mcp/eventbus-bridge.ts`) does not set it, so this is a mean over * a subset. Read it with `timedInteractions`, not with `totalInteractions`. */ readonly avgLatencyMs: number; /** * How many of `totalInteractions` carried a `durationMs` (#5782). * * Without it the mean cannot be read: 100ms over one timed edge and 100ms * over fifty are the same number with very different weight, and 0 means * "nothing was timed" rather than "instant". * * Optional so adding it does not break an external constructor of this * published type; every in-tree producer sets it. */ readonly timedInteractions?: number; /** Current bottlenecks */ readonly bottlenecks: BottleneckInfo[]; /** Detected clusters */ readonly clusters: AgentCluster[]; /** Timestamp of metrics calculation */ readonly calculatedAt: string; } /** * Interface for the SwarmObserver. */ interface ISwarmObserver { /** * Record an agent event. */ recordEvent(event: AgentEvent): void; /** * Record an interaction between two agents. */ recordInteraction(options: RecordInteractionOptions): void; /** * Get the collaboration graph. */ getCollaborationGraph(): InteractionGraph; /** * Identify bottleneck agents. */ getBottlenecks(): BottleneckInfo[]; /** * Detect emergent clusters of collaborating agents. */ getEmergentClusters(): AgentCluster[]; /** * Attribute success of a task to contributing agents. */ attributeSuccess(taskId: TaskId): Map; /** * Get swarm health metrics. */ getHealthMetrics(): SwarmHealthMetrics$1; /** * Get events for a specific trace. */ getEventsByTrace(traceId: TraceId): AgentEvent[]; /** * Get events for a specific agent. */ getEventsByAgent(agentId: AgentId): AgentEvent[]; /** * Clear all recorded data. */ clear(): void; } /** * Interface for the interaction graph. */ interface InteractionGraph { /** * Add a node (agent) to the graph. */ addNode(agentId: AgentId): void; /** * Add an edge (interaction) to the graph. */ addEdge(edge: InteractionEdge): void; /** * Get all nodes in the graph. */ getNodes(): AgentId[]; /** * Get all edges in the graph. */ getEdges(): InteractionEdge[]; /** * Get edges from a specific agent. */ getOutgoingEdges(agentId: AgentId): InteractionEdge[]; /** * Get edges to a specific agent. */ getIncomingEdges(agentId: AgentId): InteractionEdge[]; /** * Calculate degree centrality for all nodes. */ getDegreeCentrality(): Map; /** * Find strongly connected components. */ getStronglyConnectedComponents(): AgentId[][]; /** * Get edge count between two agents. */ getEdgeCount(from: AgentId, to: AgentId): number; /** * Clear the graph. */ clear(): void; } /** * nexus-agents/observability - Interaction Graph * * Directed graph for tracking agent interactions. * Supports centrality analysis, cluster detection, and bottleneck identification. * * @module observability/interaction-graph * (Source: Alignment Roadmap Phase 1, Issue #158) */ /** * Directed graph implementation for agent interactions. */ declare class DirectedInteractionGraph implements InteractionGraph { private readonly nodes; private readonly outgoing; private readonly incoming; /** * Add a node (agent) to the graph. */ addNode(agentId: AgentId): void; /** * Add an edge (interaction) to the graph. */ addEdge(edge: InteractionEdge): void; /** * Get all nodes in the graph. */ getNodes(): AgentId[]; /** * Get all edges in the graph. */ getEdges(): InteractionEdge[]; /** * Get edges from a specific agent. */ getOutgoingEdges(agentId: AgentId): InteractionEdge[]; /** * Get edges to a specific agent. */ getIncomingEdges(agentId: AgentId): InteractionEdge[]; /** * Calculate degree centrality for all nodes. * Returns normalized centrality (0-1). */ getDegreeCentrality(): Map; /** * Find strongly connected components using Kosaraju's algorithm. */ getStronglyConnectedComponents(): AgentId[][]; /** * Get edge count between two agents. */ getEdgeCount(from: AgentId, to: AgentId): number; /** * Get unique interaction partners for an agent. */ getNeighbors(agentId: AgentId): AgentId[]; /** * Calculate clustering coefficient for a node. * Measures how interconnected a node's neighbors are. */ getClusteringCoefficient(agentId: AgentId): number; /** * Get statistics about the graph. */ getStats(): GraphStats; /** * Clear the graph. */ clear(): void; } /** * Graph statistics. */ interface GraphStats { readonly nodeCount: number; readonly edgeCount: number; readonly avgLatencyMs: number; readonly successRate: number; readonly density: number; } /** * Create a new interaction graph. */ declare function createInteractionGraph(): InteractionGraph; /** * nexus-agents/observability - SwarmObserver * * Swarm-level observability for tracking agent interactions, detecting * bottlenecks, identifying emergent clusters, and attributing success. * Uses DirectedInteractionGraph for graph-based analysis. * * NOTE: This is the canonical SwarmObserver (graph-based interaction analysis). * For EventBus-based orchestration visibility, see agents/observability/OrchestrationObserver * which was previously named SwarmObserver (renamed in Issue #251). * * @module observability/swarm-observer * (Source: Alignment Roadmap Phase 1, Issue #158) */ /** * SwarmObserver implementation. */ declare class SwarmObserver implements ISwarmObserver { private readonly config; private readonly events; private readonly graph; private readonly agentStates; private readonly agentQueues; private readonly taskAgents; constructor(config?: Partial); /** * Generate OpenTelemetry-compatible trace ID (32 hex chars). */ static generateTraceId(): TraceId; /** * Generate OpenTelemetry-compatible span ID (16 hex chars). */ static generateSpanId(): SpanId; /** * Record an agent event. */ recordEvent(event: AgentEvent): void; /** * Record an interaction between two agents. */ recordInteraction(options: RecordInteractionOptions): void; /** * Get the collaboration graph. */ getCollaborationGraph(): InteractionGraph; /** * Identify bottleneck agents. */ getBottlenecks(): BottleneckInfo[]; /** * Detect emergent clusters of collaborating agents. * Uses strongly connected components + cohesion analysis. */ getEmergentClusters(): AgentCluster[]; /** * Attribute success of a task to contributing agents. */ attributeSuccess(taskId: TaskId): Map; /** * Get swarm health metrics. */ getHealthMetrics(): SwarmHealthMetrics$1; /** * Get events for a specific trace. */ getEventsByTrace(traceId: TraceId): AgentEvent[]; /** * Get events for a specific agent. */ getEventsByAgent(agentId: AgentId): AgentEvent[]; /** * Associate an agent with a task for attribution. */ registerAgentForTask(taskId: TaskId, agentId: AgentId): void; /** * Clear all recorded data. */ clear(): void; private enforceEventLimit; private updateAgentState; private updateQueueMetrics; private getOrCreateQueueMetrics; private incrementPendingMessages; private countBlockedAgents; private isTaskEvent; private countActiveAgents; private countErrorAgents; } /** * Create a new SwarmObserver instance. */ declare function createSwarmObserver(config?: Partial): ISwarmObserver; /** * Get or create the global SwarmObserver. */ declare function getSwarmObserver(config?: Partial): SwarmObserver; /** * Set the global SwarmObserver. */ declare function setSwarmObserver(observer: SwarmObserver): void; /** * Pipeline Event Types — V2 Observability (Issue #912, Phase 4-1) * * Typed event definitions for the pipeline event bus. * Every event carries a timestamp and relevant correlation IDs. * * @see docs/v2/08-observability-eventing.md * @module pipeline/event-types */ /** All valid pipeline event types. */ declare const PIPELINE_EVENT_TYPES: readonly ["task.created", "task.status_changed", "task.completed", "task.failed", "pipeline.started", "pipeline.completed", "pipeline.checkpoint", "stage.started", "stage.completed", "stage.failed", "stage.retrying", "policy.evaluated", "artifact.created", "model.called", "routing.decision", "tool.invoked", "tool.completed", "wave.started", "wave.completed", "signal.fitness_declined", "signal.swarm_unhealthy", "signal.vote_rejected"]; type PipelineEventType = (typeof PIPELINE_EVENT_TYPES)[number]; /** Base fields present on every event. */ interface BaseEvent { readonly timestamp: number; } /** Task lifecycle events. */ interface TaskCreatedEvent extends BaseEvent { readonly type: 'task.created'; readonly taskId: string; } interface TaskStatusChangedEvent extends BaseEvent { readonly type: 'task.status_changed'; readonly taskId: string; readonly from: string; readonly to: string; } interface TaskCompletedEvent extends BaseEvent { readonly type: 'task.completed'; readonly taskId: string; readonly success: boolean; } interface TaskFailedEvent extends BaseEvent { readonly type: 'task.failed'; readonly taskId: string; readonly error: string; } /** Pipeline lifecycle events. */ interface PipelineStartedEvent extends BaseEvent { readonly type: 'pipeline.started'; readonly taskId: string; readonly executionId: string; } interface PipelineCompletedEvent extends BaseEvent { readonly type: 'pipeline.completed'; readonly executionId: string; readonly success: boolean; readonly durationMs: number; } interface PipelineCheckpointEvent extends BaseEvent { readonly type: 'pipeline.checkpoint'; readonly executionId: string; readonly stepNumber: number; } /** Stage lifecycle events. */ interface StageStartedEvent extends BaseEvent { readonly type: 'stage.started'; readonly executionId: string; readonly stageId: string; readonly pluginId: string; } interface StageCompletedEvent extends BaseEvent { readonly type: 'stage.completed'; readonly executionId: string; readonly stageId: string; readonly durationMs: number; readonly success: boolean; } interface StageFailedEvent extends BaseEvent { readonly type: 'stage.failed'; readonly executionId: string; readonly stageId: string; readonly error: string; /** Error classification: retriable (transient) or fatal (permanent) (Epic #952). */ readonly errorTaxonomy?: 'retriable' | 'fatal'; /** * Concrete model id the failing stage's executor reported, when known * (#4194). Additive and optional: emitters whose stages genuinely have no * single model (local gates, consensus votes, graph nodes) omit it, and * consumers must tolerate its absence. Lets the feedback-subscriber record * real per-model outcome attribution instead of a placeholder. */ readonly model?: string; } interface StageRetryingEvent extends BaseEvent { readonly type: 'stage.retrying'; readonly executionId: string; readonly stageId: string; readonly attempt: number; } /** Policy gate events. */ interface PolicyEvaluatedEvent extends BaseEvent { readonly type: 'policy.evaluated'; readonly executionId: string; readonly gateId: string; readonly decision: string; } /** Artifact events. */ interface ArtifactCreatedEvent extends BaseEvent { readonly type: 'artifact.created'; readonly executionId: string; readonly artifactId: string; readonly artifactType: string; } /** Model call events. */ interface ModelCalledEvent extends BaseEvent { readonly type: 'model.called'; readonly executionId: string; readonly cli: string; readonly model: string; readonly tokensIn: number; readonly tokensOut: number; readonly durationMs: number; /** Agent that initiated this model call (Epic #952). */ readonly agentId?: string; /** Agent role (e.g., code_expert, security_expert) (Epic #952). */ readonly role?: string; } /** Routing decision events. */ interface RoutingDecisionEvent extends BaseEvent { readonly type: 'routing.decision'; readonly taskId: string; readonly selectedModel: string; /** Human-readable reasoning for model selection (Epic #952). */ readonly reasoning?: string; /** Routing decision path (stage:result pairs) (Epic #952). */ readonly decisionPath?: readonly string[]; } /** Signal events (#3147 P2 — close the loop). Consumed by the TuneStage. */ interface FitnessDeclinedSignalEvent extends BaseEvent { readonly type: 'signal.fitness_declined'; /** Current fitness score (0-100). */ readonly score: number; /** Governance floor the score fell below. */ readonly floor: number; /** Fitness dimension that declined, when attributable. */ readonly dimension?: string; } interface SwarmUnhealthySignalEvent extends BaseEvent { readonly type: 'signal.swarm_unhealthy'; /** Agent/CLI whose health degraded. */ readonly agentId: string; /** Human-readable degradation reason. */ readonly reason: string; } interface VoteRejectedSignalEvent extends BaseEvent { readonly type: 'signal.vote_rejected'; readonly proposalId: string; /** Approval percentage of the rejected vote (0-100). */ readonly approvalPercentage: number; /** Rejection rule categories surfaced by voters. */ readonly rejectionRules?: readonly string[]; } /** MCP tool lifecycle events (Issue #1186). */ interface ToolInvokedEvent extends BaseEvent { readonly type: 'tool.invoked'; readonly toolName: string; readonly invocationId: string; } interface ToolCompletedEvent extends BaseEvent { readonly type: 'tool.completed'; readonly toolName: string; readonly invocationId: string; readonly durationMs: number; readonly success: boolean; readonly errorMessage?: string; } /** Wave dispatch events for multi-wave worker execution (Issue #1401, Phase 6.2). */ interface WaveStartedEvent extends BaseEvent { readonly type: 'wave.started'; readonly executionId: string; readonly waveNumber: number; readonly totalWaves: number; readonly workerCount: number; readonly roles: readonly string[]; } interface WaveCompletedEvent extends BaseEvent { readonly type: 'wave.completed'; readonly executionId: string; readonly waveNumber: number; readonly totalWaves: number; readonly durationMs: number; readonly successes: number; readonly errors: number; } /** Discriminated union of all pipeline events. */ type PipelineEvent = TaskCreatedEvent | TaskStatusChangedEvent | TaskCompletedEvent | TaskFailedEvent | PipelineStartedEvent | PipelineCompletedEvent | PipelineCheckpointEvent | StageStartedEvent | StageCompletedEvent | StageFailedEvent | StageRetryingEvent | PolicyEvaluatedEvent | ArtifactCreatedEvent | ModelCalledEvent | RoutingDecisionEvent | ToolInvokedEvent | ToolCompletedEvent | WaveStartedEvent | WaveCompletedEvent | FitnessDeclinedSignalEvent | SwarmUnhealthySignalEvent | VoteRejectedSignalEvent; /** Filter for subscribing to or querying events. */ interface EventFilter { readonly type?: PipelineEventType | readonly PipelineEventType[]; readonly taskId?: string; readonly executionId?: string; readonly since?: number; } /** Event handler callback. */ type EventHandler = (event: PipelineEvent) => void; /** Unsubscribe function returned by subscribe. */ type Unsubscribe = () => void; /** * Event bus interface — fire-and-forget event emission * with typed subscriptions and bounded query. */ interface IEventBus { /** Emit an event. Handlers must not throw. */ emit(event: PipelineEvent): void; /** Subscribe to events matching filter. Returns unsubscribe function. */ subscribe(filter: EventFilter, handler: EventHandler): Unsubscribe; /** Query recent events (bounded buffer). */ query(filter: EventFilter, limit?: number): readonly PipelineEvent[]; /** Total events emitted (including evicted). */ readonly totalEmitted: number; /** Current buffer size. */ readonly bufferSize: number; } /** * decision-cost-store — durable per-decision cost rollups. * * Source: Issue #3855 (epic #3854 child, M4). * * Persists one {@link DecisionCostRecord} per governed decision (a * `consensus_vote` / `pr_review` run) so the question "what did this decision * cost?" can be answered from recorded data later — feeding Epic G's * weather_report / manifest cost profiles (#3856) and the governed-decision * cost doc (#3857). * * Mirrors the established persistence idiom: it reuses the shared * {@link JsonlStore} primitive ({@link module:config/jsonl-store}, #3762) rather * than re-forking the hydrate/append/rotate fs plumbing, and writes under the * shared learning dir like {@link module:orchestration/outcomes/outcome-store}. * Record + measure ONLY — no routing or weighting change (#3855 acceptance). * * @module observability/decision-cost-store */ /** Decision surface that incurred the cost — the gate type (#3854). */ declare const DecisionGateSchema: z.ZodEnum<{ consensus_vote: "consensus_vote"; pr_review: "pr_review"; }>; type DecisionGate = z.infer; /** One persisted per-decision cost rollup. */ declare const DecisionCostRecordSchema: z.ZodObject<{ decisionId: z.ZodString; gate: z.ZodEnum<{ consensus_vote: "consensus_vote"; pr_review: "pr_review"; }>; timestamp: z.ZodString; summary: z.ZodObject<{ billingMode: z.ZodEnum<{ api: "api"; plan: "plan"; }>; voterCount: z.ZodNumber; measuredVoters: z.ZodNumber; unmeasuredVoters: z.ZodNumber; totalInputTokens: z.ZodNumber; totalOutputTokens: z.ZodNumber; totalTokens: z.ZodNumber; totalCostUsd: z.ZodNumber; priceBasis: z.ZodOptional>; perVoter: z.ZodReadonly; cacheCreationInputTokens: z.ZodOptional; costUsd: z.ZodNumber; unmeasured: z.ZodBoolean; priceBasis: z.ZodOptional>; }, z.core.$strip>>>; perModel: z.ZodReadonly>>; }, z.core.$strip>; undeclaredOptionsDetector: z.ZodOptional; excerpt: z.ZodOptional; declaredOptionCount: z.ZodNumber; }, z.core.$strip>>; }, z.core.$strip>; type DecisionCostRecord = z.infer; /** * decision-cost-aggregate — windowed CROSS-decision cost rollups by gate type. * * Source: Issue #3856 (epic #3854 child, M4). * * Where {@link module:observability/decision-cost} rolls N voters UP into one * per-decision summary, this module rolls N *decisions* up into one per-GATE * answer: "across the recent window, what does a `consensus_vote` / `pr_review` * decision cost on average?". It is the aggregation `weather_report` surfaces * (#3856) so an operator sees what governed decisions are costing without a new * MCP tool — the report reads the {@link DecisionCostStore}'s persisted records * and folds them through this PURE function. * * Pure and deterministic: no I/O, no clock, no env reads. The caller supplies * the records (already windowed/queried) and this returns the per-gate averages. * Averages are reported alongside the decision count and the measured/unmeasured * voter split so a reader knows the confidence — a per-gate average is a FLOOR * when unmeasured voters contributed (their unknown real cost counts as 0), the * same honesty {@link module:observability/decision-cost} keeps per-decision. * * @module observability/decision-cost-aggregate */ /** Per-gate windowed cost aggregate surfaced in the weather report (#3856). */ interface GateCostAggregate { /** Which gate type these decisions came from. */ readonly gate: DecisionGate; /** Number of decisions folded in. */ readonly decisionCount: number; /** Mean total cost (USD) per decision over the window. */ readonly avgCostUsd: number; /** Mean total tokens per decision over the window. */ readonly avgTokens: number; /** Mean number of voters per decision. */ readonly avgVoters: number; /** Sum of cost (USD) across all decisions in the window. */ readonly totalCostUsd: number; /** Sum of tokens across all decisions in the window. */ readonly totalTokens: number; /** * Total voters that reported usage across the window. With `unmeasuredVoters` * this is the confidence signal: the averages are a FLOOR when * `unmeasuredVoters > 0` (unmeasured voters contribute 0, not their real cost). */ readonly measuredVoters: number; /** Total voters that reported no usage across the window. */ readonly unmeasuredVoters: number; /** * True when `unmeasuredVoters > 0` — the averages understate true spend * because some voter calls reported no usage and were folded in as 0. */ readonly costIsFloor: boolean; } /** The decision-cost section of the weather report (#3856). */ interface DecisionCostReport { /** Lookback window the records were drawn from, in ms (0 ⇒ all history). */ readonly windowMs: number; /** Per-gate-type aggregates, sorted by total cost desc then gate name. */ readonly byGate: readonly GateCostAggregate[]; /** Total decisions across all gates in the window. */ readonly totalDecisions: number; /** Total cost (USD) across all gates in the window. */ readonly totalCostUsd: number; } /** * nexus-agents/observability - Dashboard Types * * Type definitions for the execution dashboard that visualizes * SwarmObserver data in real-time. * * @module observability/dashboard-types * (Source: Alignment Roadmap Phase 1, Issue #159) */ /** * Output format for dashboard rendering. */ type DashboardFormat = 'json' | 'text' | 'markdown' | 'compact'; /** * Dashboard configuration options. */ interface DashboardConfig { /** Output format */ readonly format: DashboardFormat; /** Maximum agents to show in summary */ readonly maxAgentsShown: number; /** Maximum events to show in activity feed */ readonly maxEventsShown: number; /** Whether to show interaction graph */ readonly showGraph: boolean; /** Whether to show bottleneck warnings */ readonly showBottlenecks: boolean; /** Whether to show cluster analysis */ readonly showClusters: boolean; /** Whether to show contribution scores */ readonly showContributions: boolean; /** Time window for recent activity (ms) */ readonly timeWindowMs: number; } /** * Default dashboard configuration. */ declare const DEFAULT_DASHBOARD_CONFIG: DashboardConfig; /** * Zod schema for dashboard configuration. */ declare const DashboardConfigSchema: z.ZodObject<{ format: z.ZodDefault>; maxAgentsShown: z.ZodDefault; maxEventsShown: z.ZodDefault; showGraph: z.ZodDefault; showBottlenecks: z.ZodDefault; showClusters: z.ZodDefault; showContributions: z.ZodDefault; timeWindowMs: z.ZodDefault; }, z.core.$strip>; /** * Agent status for dashboard display. */ interface AgentStatus { readonly agentId: AgentId; readonly state: AgentState; readonly lastActivity: string; readonly messagesSent: number; readonly messagesReceived: number; readonly toolsInvoked: number; readonly errorCount: number; readonly isBottleneck: boolean; } /** * Simplified edge for graph display. */ interface GraphEdgeDisplay { readonly from: AgentId; readonly to: AgentId; readonly count: number; readonly successRate: number; readonly avgLatencyMs: number; } /** * Graph summary for dashboard display. */ interface GraphSummary { readonly nodeCount: number; readonly edgeCount: number; readonly density: number; readonly stronglyConnectedComponents: number; readonly topEdges: GraphEdgeDisplay[]; readonly centralAgents: Array<{ agentId: AgentId; centrality: number; }>; } /** * Activity feed item. */ interface ActivityItem { readonly timestamp: string; readonly agentId: AgentId; readonly eventType: AgentEvent['eventType']; readonly summary: string; readonly severity: 'info' | 'warning' | 'error'; readonly traceId: TraceId; } /** * Complete dashboard snapshot. */ interface DashboardSnapshot { /** Snapshot timestamp */ readonly timestamp: string; /** Swarm health summary */ readonly health: SwarmHealthMetrics$1; /** Individual agent statuses */ readonly agents: AgentStatus[]; /** Interaction graph summary */ readonly graph: GraphSummary; /** Recent activity feed */ readonly activity: ActivityItem[]; /** Current bottlenecks */ readonly bottlenecks: BottleneckInfo[]; /** Detected clusters */ readonly clusters: AgentCluster[]; /** Top contributors (if task context) */ readonly contributions: ContributionScore[]; /** Active traces */ readonly activeTraces: TraceId[]; } /** * Partial dashboard options for selective updates. */ interface DashboardUpdateOptions { readonly includeHealth?: boolean | undefined; readonly includeAgents?: boolean | undefined; readonly includeGraph?: boolean | undefined; readonly includeActivity?: boolean | undefined; readonly includeBottlenecks?: boolean | undefined; readonly includeClusters?: boolean | undefined; readonly includeContributions?: boolean | undefined; } /** * Dashboard renderer interface. */ interface IDashboardRenderer { /** * Render the dashboard snapshot to the configured format. */ render(snapshot: DashboardSnapshot): string; /** * Render just the health section. */ renderHealth(health: SwarmHealthMetrics$1): string; /** * Render the agent status table. */ renderAgents(agents: AgentStatus[]): string; /** * Render the interaction graph. */ renderGraph(graph: GraphSummary): string; /** * Render the activity feed. */ renderActivity(activity: ActivityItem[]): string; /** * Render bottleneck warnings. */ renderBottlenecks(bottlenecks: BottleneckInfo[]): string; /** * Render cluster analysis. */ renderClusters(clusters: AgentCluster[]): string; } /** * Dashboard service interface. */ interface IDashboard { /** * Get current dashboard snapshot. */ getSnapshot(options?: DashboardUpdateOptions): DashboardSnapshot; /** * Render dashboard to string in configured format. */ render(options?: DashboardUpdateOptions): string; /** * Get dashboard configuration. */ getConfig(): DashboardConfig; /** * Update dashboard configuration. */ updateConfig(config: Partial): void; /** * Subscribe to dashboard updates. */ subscribe(callback: (snapshot: DashboardSnapshot) => void): () => void; } /** * nexus-agents/observability - Dashboard Renderer * * Renders dashboard snapshots to various output formats (text, JSON, markdown). * * @module observability/dashboard-renderer * (Source: Alignment Roadmap Phase 1, Issue #159) */ /** * Text-based dashboard renderer for terminal output. */ declare class TextDashboardRenderer implements IDashboardRenderer { private readonly config; constructor(config: DashboardConfig); render(snapshot: DashboardSnapshot): string; private renderHeader; renderHealth(health: SwarmHealthMetrics$1): string; renderAgents(agents: AgentStatus[]): string; renderGraph(graph: GraphSummary): string; renderActivity(activity: ActivityItem[]): string; renderBottlenecks(bottlenecks: BottleneckInfo[]): string; renderClusters(clusters: AgentCluster[]): string; private renderBar; private getStateIcon; private getSeverityIcon; } /** * JSON dashboard renderer for programmatic consumption. */ declare class JsonDashboardRenderer implements IDashboardRenderer { render(snapshot: DashboardSnapshot): string; renderHealth(health: SwarmHealthMetrics$1): string; renderAgents(agents: AgentStatus[]): string; renderGraph(graph: GraphSummary): string; renderActivity(activity: ActivityItem[]): string; renderBottlenecks(bottlenecks: BottleneckInfo[]): string; renderClusters(clusters: AgentCluster[]): string; } /** * Compact single-line renderer for logging. */ declare class CompactDashboardRenderer implements IDashboardRenderer { render(snapshot: DashboardSnapshot): string; renderHealth(health: SwarmHealthMetrics$1): string; renderAgents(agents: AgentStatus[]): string; renderGraph(graph: GraphSummary): string; renderActivity(activity: ActivityItem[]): string; renderBottlenecks(bottlenecks: BottleneckInfo[]): string; renderClusters(clusters: AgentCluster[]): string; } /** * Create a dashboard renderer for the specified format. */ declare function createDashboardRenderer(config: DashboardConfig): IDashboardRenderer; /** * nexus-agents/observability - Dashboard * * Real-time execution dashboard for visualizing SwarmObserver data. * Provides agent status, interaction graphs, bottleneck detection, * and activity feeds. * * @module observability/dashboard * (Source: Alignment Roadmap Phase 1, Issue #159) */ /** * Dashboard implementation that consumes SwarmObserver data. */ declare class Dashboard implements IDashboard { private config; private readonly observer; private renderer; private readonly subscribers; constructor(observer: ISwarmObserver, config?: Partial); getSnapshot(options?: DashboardUpdateOptions): DashboardSnapshot; render(options?: DashboardUpdateOptions): string; getConfig(): DashboardConfig; updateConfig(config: Partial): void; subscribe(callback: (snapshot: DashboardSnapshot) => void): () => void; /** * Notify all subscribers of an update. */ notifySubscribers(): void; private normalizeOptions; private getDefaultOptions; private buildAgentStatuses; private buildAgentStatus; private buildActivityFeed; private getContributions; private getActiveTraces; private emptyHealth; private emptyGraphSummary; } /** * Create a new dashboard instance. */ declare function createDashboard(observer: ISwarmObserver, config?: Partial): Dashboard; /** * Routing Metrics Collector * * Collects and visualizes routing effectiveness metrics for the CLI adapter system. * Enables observability into LinUCB learning, model selection patterns, and task outcomes. * * @module observability/routing-metrics * (Source: Alignment Roadmap Phase 1, Issue #171) */ /** Configuration for the metrics collector. */ interface RoutingMetricsConfig { readonly maxRecords: number; readonly retentionHours: number; } /** * Collects routing decisions and outcomes to compute effectiveness metrics. */ declare class RoutingMetricsCollector { private readonly config; private readonly decisions; private readonly outcomes; constructor(config?: Partial); /** * Record a routing decision. */ recordDecision(record: RoutingRecord): void; /** * Record an outcome for a routing decision. */ recordOutcome(record: OutcomeRecord): void; /** * Get routing metrics for a time period. */ getMetrics(periodHours?: number): RoutingMetrics; /** * Generate ASCII dashboard output. */ renderDashboard(config?: Partial): string; /** * Get metrics as JSON for machine-readable output. */ toJSON(periodHours?: number): string; /** * Clear all collected data. */ reset(): void; private enforceRetention; private aggregateByModel; private calculateRewardTrend; } /** * Create a RoutingMetricsCollector instance. */ declare function createRoutingMetricsCollector(config?: Partial): RoutingMetricsCollector; /** * Validation Statistics Types * * Type definitions for statistical analysis in the learning validation dashboard. * Supports confidence intervals, hypothesis testing, and A/B test comparisons. * * @module learning/validation-stats-types * (Source: Issue #273 - Learning Validation Dashboard) */ /** * Confidence interval result with bounds and metadata. */ interface ConfidenceInterval { /** Lower bound of the interval */ readonly lower: number; /** Upper bound of the interval */ readonly upper: number; /** Point estimate (center of interval) */ readonly estimate: number; /** Confidence level (e.g., 0.95 for 95% CI) */ readonly confidence: number; /** Sample size used */ readonly n: number; /** Standard error */ readonly standardError: number; /** * Whether the interval was computed from data (#5760 item 3). * * `false` means the sample was empty and `lower`/`upper`/`estimate` carry no * information — they are whatever the empty branch happened to return, not a * result. Read this before reading the bounds. * * The bounds alone cannot say it. `meanConfidenceInterval([])` returned * `lower === upper === 0` — the strongest possible precision claim, over no * data. `proportionConfidenceInterval(0, 0)` returned `[0, 1]`, which is * honest by luck rather than by construction: a proportion's domain happens * to be bounded, so its uninformative interval is expressible, and a mean's * is not. `calculateDifferenceCI` divided by `(total1 || 1)` and produced a * finite interval from nothing at all. * * Named for the vocabulary this repo already uses for exactly this — * `tokensMeasured`, `policyEvaluated`, `gapsMeasured`, `routerTypeMeasured`. * REQUIRED rather than optional so the compiler names every producer; * optional would let a new one stay silent, which is the state this removes. * * Ratified 5 of 6 approvers at supermajority (#5760). Infinity and NaN * bounds were both rejected for the same reason: each serialises to `null` * in JSON, turning a loud in-process signal into a silent persisted one. */ readonly measured: boolean; } /** * Result of a two-sample comparison test. */ interface ComparisonResult { /** P-value from the test */ readonly pValue: number; /** Whether result is significant at alpha level */ readonly significant: boolean; /** Alpha level used for significance */ readonly alpha: number; /** Difference in success rates (group1 - group2) */ readonly difference: number; /** Confidence interval for the difference */ readonly differenceCI: ConfidenceInterval; /** Effect size (Cohen's h for proportions) */ readonly effectSize: number; /** Sample sizes */ readonly n1: number; readonly n2: number; } /** * Descriptive statistics for a distribution. */ interface DistributionStats { readonly mean: number; readonly median: number; readonly stdDev: number; readonly variance: number; readonly min: number; readonly max: number; readonly n: number; /** Percentiles: p5, p25, p50, p75, p95 */ readonly percentiles: { readonly p5: number; readonly p25: number; readonly p50: number; readonly p75: number; readonly p95: number; }; } /** * Regret analysis result comparing actual vs optimal decisions. */ interface RegretAnalysis { /** * Total cumulative regret, or `null` when no decision was comparable (#5255). * * These three were plain `number` and returned `0`/`0`/`1` for an empty * decision set — which the dashboard rendered as "Cumulative Regret: 0.00" * and "Optimal Decision Rate: 100.0%" with a full progress bar. A perfect * routing record asserted over nothing is an absent measurement wearing a * good score, and the primary consumer of these numbers is the learning loop * itself, which has no way to consult a sibling flag. * * `null` means UNMEASURED — no comparable decision existed. It does not mean * zero regret; that is `0`, and the two are now distinguishable. */ readonly cumulativeRegret: number | null; /** Average regret per decision, or `null` when unmeasured — see above. */ readonly avgRegret: number | null; /** Number of decisions analyzed. Stays numeric: 0 is the true count. */ readonly totalDecisions: number; /** Number of suboptimal decisions. Stays numeric: 0 is the true count. */ readonly suboptimalDecisions: number; /** Share of optimal decisions, or `null` when unmeasured — see above. */ readonly optimalRate: number | null; /** Regret per model (how much worse each model performed vs best) */ readonly regretPerModel: Record; } /** * Win/loss analysis comparing routing choices. */ interface WinLossAnalysis { /** Model name */ readonly model: string; /** Number of times this model won (best outcome) */ readonly wins: number; /** Number of times this model lost (not best outcome) */ readonly losses: number; /** Number of ties */ readonly ties: number; /** Win rate */ readonly winRate: number; /** Confidence interval for win rate */ readonly winRateCI: ConfidenceInterval; } /** * Variant result summary for experiment results. */ interface VariantResultSummary { readonly name: string; readonly n: number; readonly successRate: number; readonly avgReward: number; readonly successRateCI: ConfidenceInterval; } /** * A/B test experiment result. */ interface ExperimentResult { /** Experiment identifier */ readonly experimentId: string; /** Control group statistics */ readonly control: VariantResultSummary; /** Treatment group statistics */ readonly treatment: VariantResultSummary; /** Comparison between groups */ readonly comparison: ComparisonResult; /** Relative improvement (treatment vs control) */ readonly relativeImprovement: number; /** * Whether {@link relativeImprovement} was computed from a control rate that * could support a ratio. * * `false` means the control measured 0 successes, so the relative improvement * is unbounded and the accompanying `0` is a placeholder — NOT "treatment and * control performed identically", which is what `0` reads as on that scale. A * control of 0/50 is a real measurement; the ratio over it is the thing that * does not exist. * * `calculateRegret` solved the same problem with `null` (#5255). This field * carries the same information without widening a public `number` to * `number | null`, which is a breaking change for readers. */ readonly relativeImprovementMeasured: boolean; /** Whether experiment has enough data for valid conclusions */ readonly hasMinimumSampleSize: boolean; /** Minimum recommended sample size per group */ readonly recommendedSampleSize: number; /** * Whether {@link recommendedSampleSize} was computed from a baseline the * control actually measured. * * `false` means the control has **no observations**, so the `0` baseline * `calculateMinSampleSize` was handed is a default, not a rate. The number it * returns is real arithmetic over a fabricated input and comes out several * times too small — in the direction that tells an operator to stop * collecting early, which is exactly the reader this field exists to warn. * * Note the gate is `control.n > 0`, NOT `control.successRate > 0`: a control * of 0/50 is a measured baseline of 0.0 and a legitimate input here. That is * a different question from the one {@link relativeImprovementMeasured} * answers, which is whether a *ratio over* the control rate exists — hence * two markers rather than one shared flag (#5857). */ readonly recommendedSampleSizeMeasured: boolean; } /** * Model performance matrix entry (model × task type). */ interface PerformanceMatrixEntry { readonly model: string; readonly taskType: string; readonly n: number; readonly successRate: number; readonly avgReward: number; readonly avgLatencyMs: number; readonly successRateCI: ConfidenceInterval; } /** * Options for statistical calculations. */ interface StatisticalOptions { /** Confidence level for intervals (default: 0.95) */ readonly confidence?: number; /** Alpha level for significance testing (default: 0.05) */ readonly alpha?: number; /** Minimum sample size for valid inference (default: 30) */ readonly minSampleSize?: number; /** Use continuity correction for proportions (default: true) */ readonly useContinuityCorrection?: boolean; } /** * Default statistical options. */ declare const DEFAULT_STATISTICAL_OPTIONS: Required; /** * Validation Dashboard Types * * Type definitions for the learning validation dashboard. * * @module observability/validation-dashboard-types * (Source: Issue #273 - Learning Validation Dashboard) */ /** * Time period for aggregation. */ type TimePeriod = '1h' | '24h' | '7d' | '30d' | 'all'; /** * Model performance summary with confidence intervals. */ interface ModelPerformanceSummary { /** Model/CLI name */ readonly model: string; /** Number of routing decisions */ readonly n: number; /** Success rate with confidence interval */ readonly successRate: number; readonly successRateCI: ConfidenceInterval; /** Average reward with distribution stats */ readonly avgReward: number; readonly rewardStats: DistributionStats; /** Average latency in milliseconds */ readonly avgLatencyMs: number; /** * Win rate vs other models, over the {@link comparableN} outcomes that carried * counterfactual rewards. Unmeasured — `comparableN === 0` — reads `0` here * for compatibility; check `comparableN` before treating it as a defeat (#5650). */ readonly winRate: number; readonly winRateCI: ConfidenceInterval; /** Number of outcomes the win rate was computed over; 0 means unmeasured (#5650). */ readonly comparableN: number; /** Cost efficiency (reward per token) */ readonly costEfficiency: number; } /** * Task type performance breakdown. */ interface TaskTypePerformance { /** Task type */ readonly taskType: string; /** Performance per model for this task type */ readonly modelPerformance: readonly ModelPerformanceSummary[]; /** Best performing model */ readonly bestModel: string; /** Worst performing model */ readonly worstModel: string; } /** * Learning progress metrics. */ interface LearningProgress { /** * LinUCB exploration rate, or `null` when nothing was recorded (#5255). * * `0` was the empty-case value and rendered as "0.0%" — indistinguishable * from a real fully-greedy policy, which is a legitimate 0.0%. `null` means * UNMEASURED; `0` means measured-and-zero. */ readonly explorationRate: number | null; readonly explorationRateTrend: number; /** Cumulative regret, or `null` when no decision was comparable. */ readonly cumulativeRegret: number | null; /** Average regret per decision, or `null` when unmeasured. */ readonly avgRegret: number | null; /** Optimal decision rate, or `null` when unmeasured. */ readonly optimalRate: number | null; /** Feature importance ranking */ readonly featureImportance: readonly { readonly feature: string; readonly importance: number; }[]; /** Learning convergence metric (0-1, 1 = converged) */ /** * Convergence score, or `null` when no feature weights were recorded (#5255). * * The empty case returned `0`, which reads as WORST-possible convergence — * `Math.exp(-variance)` only approaches 0 and never reaches it, so a literal * 0% could not have been a real reading. */ readonly convergenceScore: number | null; } /** * Dashboard summary. */ interface DashboardSummary { /** Period covered */ readonly period: TimePeriod; readonly periodStart: string; readonly periodEnd: string; /** Total decisions in period */ readonly totalDecisions: number; /** Total outcomes recorded */ readonly totalOutcomes: number; /** Overall success rate */ readonly overallSuccessRate: number; readonly overallSuccessRateCI: ConfidenceInterval; /** Overall average reward */ readonly overallAvgReward: number; /** Model performance summaries */ readonly modelPerformance: readonly ModelPerformanceSummary[]; /** Task type breakdown */ readonly taskTypePerformance: readonly TaskTypePerformance[]; /** Learning progress metrics */ readonly learningProgress: LearningProgress; /** Health indicators */ readonly healthIndicators: DashboardHealthIndicators; } /** * Dashboard health indicators. */ interface DashboardHealthIndicators { /** Whether we have enough data for statistical inference */ readonly hasMinimumData: boolean; /** * Whether learning is progressing, or `null` when unmeasured (#5255). * * This was `boolean` and computed from `avgRegret`/`optimalRate`, whose empty * case returned `0`/`1` — so it answered "yes" on the strength of no data. * #4714 spotted that and guarded only the aggregate `healthScore`; the guard * keys on total outcomes, which is a DIFFERENT collection from the one these * metrics read, so on a live system it passed and the fabricated verdict * flowed through anyway. */ readonly isLearning: boolean | null; /** * Whether exploration is in the healthy 10-20% range, or `null` when nothing * was recorded (#5255). * * Previously rendered `✗ Healthy Exploration` over ZERO samples — asserting a * health *failure* from absence — while the warning that would have explained * it was gated behind `explorationHistory.length > 10`, so the one disclosing * line was exactly the suppressed one. */ readonly healthyExploration: boolean | null; /** Whether any model is significantly underperforming */ readonly noUnderperformers: boolean; /** Overall health score (0-1) */ /** * Overall health, or `null` when there is not enough data to score (#4714). * * `null` is not zero and not a bad score — it means the indicators would be * defaults rather than measurements. Render it as "unmeasured"; do not * coerce it to a number. */ readonly healthScore: number | null; /** Warning messages */ readonly warnings: readonly string[]; } /** * Dashboard filter options. */ interface DashboardFilter { /** Time period */ readonly period?: TimePeriod; /** Filter to specific models */ readonly models?: readonly string[]; /** Filter to specific task types */ readonly taskTypes?: readonly string[]; /** Minimum sample size for inclusion */ readonly minSampleSize?: number; } /** * ASCII dashboard render options. */ interface DashboardRenderOptions { /** Show confidence intervals */ readonly showConfidenceIntervals?: boolean; /** Show task type breakdown */ readonly showTaskTypes?: boolean; /** Show learning progress */ readonly showLearningProgress?: boolean; /** Show feature importance */ readonly showFeatureImportance?: boolean; /** Maximum width in characters */ readonly maxWidth?: number; } /** * Default dashboard render options. */ declare const DEFAULT_DASHBOARD_RENDER_OPTIONS: Required; /** * Outcome record for dashboard aggregation. */ interface DashboardOutcome { readonly model: string; readonly taskType: string; readonly success: boolean; readonly reward: number; readonly latencyMs: number; readonly tokensUsed: number; readonly timestamp: number; readonly allModelRewards?: Record; } /** * Validation Dashboard * * Aggregates learning metrics and provides ASCII/JSON visualization. * * @module observability/validation-dashboard * (Source: Issue #273 - Learning Validation Dashboard) */ /** * Validation Dashboard implementation. */ declare class ValidationDashboard { private outcomes; private explorationHistory; private featureWeights; /** Record an outcome for dashboard aggregation. Evicts oldest when cap reached. */ recordOutcome(outcome: DashboardOutcome): void; /** Record exploration rate snapshot. */ recordExplorationRate(rate: number): void; /** Record feature weights for importance tracking. */ recordFeatureWeights(weights: Record): void; /** Get dashboard summary with all metrics. */ getSummary(filter?: DashboardFilter): DashboardSummary; /** Render dashboard as ASCII text. */ renderDashboard(filter?: DashboardFilter, options?: DashboardRenderOptions): string; /** Clear all recorded data. */ clear(): void; private filterOutcomes; private calculateHealthIndicators; private checkLearningProgress; private checkExplorationHealth; private checkUnderperformers; } /** Create a validation dashboard instance. */ declare function createValidationDashboard(): ValidationDashboard; /** * CollaborationEventBus to MCP Server Bridge * * Bridges CollaborationEventBus events to SwarmObserver for observability in * Claude Desktop context. Provides visibility into agent-to-agent * communication that would otherwise be opaque. * * @module mcp/eventbus-bridge * (Source: Issue #307 - CollaborationEventBus MCP integration) */ /** * Result of bridge initialization. */ interface EventBusBridgeResult { /** Whether the bridge was initialized */ readonly initialized: boolean; /** Number of active subscriptions */ readonly subscriptionCount: number; /** Cleanup function to call on shutdown */ readonly cleanup: () => void; } /** * Initializes the CollaborationEventBus bridge with SwarmObserver integration. * * Subscribes to configured event patterns and: * 1. Logs events at appropriate levels (debug for frequent, info for important) * 2. Records interactions to SwarmObserver for graph-based analysis * 3. Tracks event statistics for observability * * @param observer - SwarmObserver instance for interaction tracking * @param logger - Logger instance for event logging * @param config - Optional CollaborationEventBus configuration * @returns Bridge result with cleanup function */ declare function initializeEventBusBridge(observer: SwarmObserver, logger: ILogger, config?: Partial): EventBusBridgeResult; /** * Gets CollaborationEventBus statistics for observability reporting. */ declare function getEventBusStats(): { eventsEmitted: number; activeSubscriptions: number; historySize: number; errorCount: number; }; /** * nexus-agents/mcp - Prompt Template Definitions * * Declarative prompt templates for MCP clients. * Each definition specifies a name, description, Zod args schema, * and a function that builds the prompt messages from validated args. * * (Source: MCP Protocol 2025-11-25) */ /** * A single message in a prompt template. */ interface PromptMessage { readonly role: 'user' | 'assistant'; readonly content: { readonly type: 'text'; readonly text: string; }; } /** * Declarative definition of an MCP prompt template. * * - `argsSchema`: Zod shape passed to `server.registerPrompt` * - `buildMessages`: produces the message array from validated args */ interface PromptDefinition { readonly name: string; readonly description: string; readonly argsSchema: Record; readonly buildMessages: (args: Record) => readonly PromptMessage[]; } /** * All registered MCP prompt templates. * * Each entry provides a Zod args schema for validation and a message builder. */ declare const PROMPT_DEFINITIONS: readonly PromptDefinition[]; /** * nexus-agents/mcp - Prompt Registration * * Registers all MCP prompt templates on the server. * Each prompt is defined declaratively in prompt-definitions.ts * and wired here via `server.registerPrompt()`. * * (Source: MCP Protocol 2025-11-25) */ /** * Result of prompt registration. */ interface PromptRegistrationResult { /** Names of registered prompts */ readonly prompts: readonly string[]; } /** * Registers all prompt templates on the MCP server. * * Iterates `PROMPT_DEFINITIONS` and calls `server.registerPrompt()` for each. * The SDK handles argument validation via the Zod schemas defined in each prompt. * * @param server - The MCP server instance * @param logger - Logger for registration events * @returns The list of registered prompt names */ declare function registerPrompts(server: McpServer, logger: ILogger): PromptRegistrationResult; /** * nexus-agents/mcp/resources - Models Resource * * Exposes the model capabilities matrix as an MCP resource. * Provides read-only access to all supported AI model metadata * including pricing, quality scores, context windows, and CLI mappings. * * @module mcp/resources/models-resource * (Source: Issue #1288) */ /** * Registers the `nexus://models` resource with the MCP server. * * Exposes the full model capabilities matrix (13 models) as a * read-only JSON resource. Data is sourced from the canonical * model registry (via `getInTreeCapabilitiesMatrix()` — backed by * the ModelRegistry's in-tree entries, #2546 slice C3). * * @param server - MCP server instance * @param logger - Logger for registration events */ declare function registerModelsResource(server: McpServer, logger: ILogger): void; /** * nexus-agents/mcp/resources - Research Resource * * Exposes the research paper registry as an MCP resource. * Provides read-only access to tracked papers, techniques, * and research statistics. * * @module mcp/resources/research-resource * (Source: Issue #1288) */ /** * Registers the `nexus://research/papers` resource with the MCP server. * * Exposes the research registry (papers, techniques, stats) as a * read-only JSON resource. Gracefully returns an empty result when * the registry YAML files are not present. * * @param server - MCP server instance * @param logger - Logger for registration events */ declare function registerResearchResource(server: McpServer, logger: ILogger): void; /** * nexus-agents/mcp/resources - Experts Resource * * Exposes the available expert roles and their capabilities * as an MCP resource. Provides read-only access to expert * metadata without exposing system prompts. * * @module mcp/resources/experts-resource * (Source: Issue #1288) */ /** * Registers the `nexus://experts` resource with the MCP server. * * Exposes the list of available expert roles (10 built-in experts) * with their names, descriptions, and capabilities as a read-only * JSON resource. * * @param server - MCP server instance * @param logger - Logger for registration events */ declare function registerExpertsResource(server: McpServer, logger: ILogger): void; /** * nexus-agents/mcp/resources - MCP Resource Registration * * Aggregates all MCP resource registrations into a single entry point. * Resources expose read-only metadata (models, research, experts) * that MCP clients can discover and read. * * @module mcp/resources * (Source: Issue #1288) */ /** * Registers all MCP resources with the server. * * Currently registers 4 resources: * - `nexus://models` - AI model capabilities matrix (static) * - `nexus://available-models` - live discovered model set per transport (#3406) * - `nexus://research/papers` - Research paper registry * - `nexus://experts` - Available expert agent roles * * @param server - MCP server instance * @param logger - Optional logger (creates default if not provided) */ declare function registerResources(server: McpServer, logger?: ILogger): void; /** * Input schema for create_expert tool. */ declare const CreateExpertInputSchema: z.ZodObject<{ role: z.ZodEnum<{ code_expert: "code_expert"; architecture_expert: "architecture_expert"; security_expert: "security_expert"; documentation_expert: "documentation_expert"; testing_expert: "testing_expert"; devops_expert: "devops_expert"; research_expert: "research_expert"; pm_expert: "pm_expert"; ux_expert: "ux_expert"; infrastructure_expert: "infrastructure_expert"; qa_expert: "qa_expert"; data_visualization_expert: "data_visualization_expert"; }>; modelPreference: z.ZodOptional; }, z.core.$strip>; /** * Type for validated create expert input. */ type CreateExpertInput = z.infer; /** * Expert factory interface for dependency injection. */ interface IExpertFactory { createBuiltIn(type: BuiltInExpertType, options?: { modelOverrides?: { modelId?: string; }; recoveryPolicy?: ExpertRecoveryPolicy; }): { ok: true; value: Expert; } | { ok: false; error: Error; }; } /** * Dependencies for create_expert tool. */ interface CreateExpertDeps extends BaseMcpToolDeps { /** Expert factory for creating experts */ expertFactory: IExpertFactory; /** Registry to track created experts */ expertRegistry: Map; /** Optional CLI detection cache for checking available CLIs (Issue #747) */ cliCache?: ICliDetectionCache; /** Model adapter for expert execution (Issue #808) */ modelAdapter?: IModelAdapter; } /** * Response from create_expert tool. */ interface CreateExpertResponse { /** Unique expert ID */ expertId: string; /** Expert role */ role: string; /** List of capabilities */ capabilities: readonly AgentCapability[]; /** Expert status */ status: 'ready'; } /** * Registers the create_expert tool with the MCP server. * * Uses createSecureHandler for standardized security middleware (Issue #531). * Includes timeout protection for CVE-2026-0621 mitigation (Issue #271). * * @category MCP * @param server - MCP server instance * @param deps - Tool dependencies */ declare function registerCreateExpertTool(server: McpServer, deps: CreateExpertDeps): void; /** * Creates default dependencies for the create_expert tool. * * @param rateLimiter - Rate limiter for throttling tool calls (required) * @param logger - Optional logger instance * @returns CreateExpertDeps with default factory and empty registry */ declare function createDefaultDeps(rateLimiter: RateLimiter$1, logger?: ILogger): CreateExpertDeps; /** * Gets the list of available expert roles. */ declare function getAvailableRoles(): string[]; /** * Gets capabilities for a given expert role. */ declare function getCapabilitiesForRole(role: string): readonly AgentCapability[] | undefined; /** * Input schema for the run_workflow tool. */ declare const RunWorkflowInputSchema: z.ZodObject<{ idempotencyKey: z.ZodOptional; dispatch: z.ZodOptional; mode: z.ZodOptional>; template: z.ZodString; inputs: z.ZodRecord; dryRun: z.ZodDefault>; timeoutMs: z.ZodOptional; }, z.core.$strip>; type RunWorkflowInput = z.infer; /** * Workflow execution result returned by the tool. */ interface WorkflowToolResult { executionId: string; workflowName: string; status: 'completed' | 'failed'; stepResults: StepResultSummary[]; output: unknown; durationMs: number; } /** * Simplified step result for tool output. */ interface StepResultSummary { stepId: string; status: 'success' | 'failed' | 'skipped'; durationMs: number; error?: string; } /** * Dry run validation result. */ interface DryRunResult { valid: boolean; workflowName: string; stepCount: number; inputsProvided: string[]; inputsRequired: string[]; inputsMissing: string[]; validationErrors: string[]; } /** * Dependencies required by the run_workflow tool. */ interface RunWorkflowDeps extends BaseMcpToolDeps { /** * Engine used to ENUMERATE and load templates — `listTemplates`, * `getTemplateByName`, `loadTemplate`. Never used to execute. * * Listing needs no model adapter, so this engine is constructible on a fresh * install with no credentials. That is the capability split #5116 turns on: * enumerating workflows and running them have different prerequisites. */ workflowEngine: IWorkflowEngine; /** * Resolves the engine that actually EXECUTES, at call time (#5116). * * A THUNK rather than a value because constructing an executing engine throws * `WorkflowExecutionUnavailableError` under the #507 fail-safe when nothing * can execute for real — doing that eagerly at tool registration killed the * whole server, all 47 tools, over one unconfigured adapter. * * OPTIONAL rather than required, by unanimous panel decision. It was briefly * required, which is how all eight internal call sites were enumerated by the * compiler — that value is already banked. Keeping it required would make * this a breaking change to a publicly exported type (`exports/mcp.ts`) and * gate a p1 correctness fix behind a major version. * * Defaulting to `workflowEngine` is semantically correct for an external * caller, not merely compile-compatible: their single engine genuinely serves * both listing and execution, so the fallback preserves exactly what they had. * The residual hazard — a future INTERNAL call site omitting this and * executing against a listing engine — is covered two ways: a test asserting * the production registration supplies it, and the listing engine failing * closed rather than returning a fabricated success. */ resolveExecutionEngine?: (() => IWorkflowEngine) | undefined; /** MCP notifier for client-visible logging (Issue #974) */ notifier?: IMcpNotifier | undefined; } /** * nexus-agents/mcp - Run Workflow Tool * * MCP tool for executing workflow templates with the workflow engine. * Supports both built-in templates and custom template paths. * * @module mcp/tools/run-workflow * (Refactored: Issue #531 - Use createSecureHandlerFactory) */ /** * Register the run_workflow tool with an MCP server. * * Uses createSecureHandler for standardized security middleware (Issue #531). * Includes timeout protection for CVE-2026-0621 mitigation (Issue #271). * * @category MCP * @param server - MCP server instance * @param deps - Tool dependencies */ declare function registerRunWorkflowTool(server: McpServer, deps: RunWorkflowDeps): void; /** * nexus-agents/orchestration - Workflow Pattern Router Types * * Type definitions for the intelligent workflow pattern selection system. * The router maps task characteristics to the optimal orchestration pattern. * * @module orchestration/workflow-router-types * (Source: Issue #844 — Intelligent Workflow Pattern Router) */ /** * Orchestration patterns available in nexus-agents. * Each maps to a concrete execution module. */ type WorkflowPattern = 'sequential' | 'wave' | 'graph' | 'consensus' | 'aflow' | 'puppeteer'; /** * Dependency structure classification for a task. */ type DependencyStructure = 'linear' | 'dag' | 'independent' | 'unknown'; /** * Time constraint urgency level. * * `'relaxed'` is accepted as a caller hint but no inference path produces it: * `enrichSignals` in `workflow-router.ts` emits only `'urgent'` or `'normal'`, * and the sole consumer (`ruleNovelTask`) tests only for `'urgent'`, so * `'relaxed'` and `'normal'` route identically. Pinned by * `workflow-router.test.ts` (#5097). */ type TimeConstraint = 'urgent' | 'normal' | 'relaxed'; /** * Quality requirement level. * * @deprecated Never read. No routing rule consults `TaskSignals.qualityRequirement`; * the value is accepted and silently dropped (a caller passing it through * `meta-orchestrator.ts` `select()` has it spread into `TaskSignals` and ignored). * Do not confuse it with the analyzer-extracted `analysis.constraints.quality` * string, which IS read for clarification prompts. Removal from the public * surface is tracked in #5097. */ type QualityRequirement = 'best-effort' | 'high' | 'critical'; /** * Input signals for workflow routing decisions. * Combines explicit caller hints with SharedTaskAnalyzer output. */ interface TaskSignals { /** Natural language task description */ readonly description: string; /** Estimated number of subtasks (optional hint) */ readonly subtaskCount?: number | undefined; /** Whether subtasks depend on each other (optional hint) */ readonly hasDependencies?: boolean | undefined; /** Dependency structure classification (optional hint) */ readonly dependencyStructure?: DependencyStructure | undefined; /** Whether multi-perspective consensus is needed */ readonly requiresConsensus?: boolean | undefined; /** Whether this task type has been seen before */ readonly isNovel?: boolean | undefined; /** Time urgency */ readonly timeConstraint?: TimeConstraint | undefined; /** * Quality requirement level. * * @deprecated Never read — no routing rule consults this field, so setting it * does not change the decision (pinned by `workflow-router.test.ts`). A caller * passing it through `meta-orchestrator.ts` `select()` has it silently * dropped. Removal is tracked in #5097. */ readonly qualityRequirement?: QualityRequirement | undefined; /** Force a specific pattern (escape hatch per DevEx feedback) */ readonly forcePattern?: WorkflowPattern | undefined; } /** * Routing decision with explanation. */ interface RoutingDecision$1 { /** Selected workflow pattern */ readonly pattern: WorkflowPattern; /** Human-readable explanation of why this pattern was selected */ readonly reasoning: string; /** * The rule's PRIOR for this pattern (0-1) — NOT a measurement of this task * (#5957, same call as #5119). Every rule returns an authored literal, so * two tasks claimed by the same rule report the same number however much * the analyzer's own signals differ. Read it as "how much this repo trusts * this rule", never as "how well this task fits". */ readonly confidence: number; /** Which rules matched during selection */ readonly matchedRules: readonly string[]; /** Alternative patterns that were considered */ readonly alternatives: readonly WorkflowPattern[]; /** Analysis result from SharedTaskAnalyzer */ readonly analysis: TaskAnalysisResult; /** Whether the task should be clarified before execution (Issue #904) */ readonly needsClarification?: boolean; /** Suggested clarification questions when needsClarification is true */ readonly suggestedQuestions?: readonly string[]; /** Capability gap report — what's available vs what's needed (Issue #906) */ readonly capabilityGaps?: CapabilityGapReport; } /** * Options for the workflow router. */ interface WorkflowRouterOptions { /** Dry run mode — return decision without executing (per DevEx feedback) */ readonly dryRun?: boolean | undefined; } /** * Recorded outcome for pattern performance tracking. */ interface PatternOutcome { /** Pattern that was used */ readonly pattern: WorkflowPattern; /** Task type from analyzer */ readonly taskType: string; /** Whether execution succeeded */ readonly success: boolean; /** Duration in milliseconds */ readonly durationMs: number; /** Timestamp of recording */ readonly timestamp: number; } /** * Aggregated performance metrics for a pattern-task combination. */ interface PatternMetrics { readonly pattern: WorkflowPattern; readonly taskType: string; readonly totalExecutions: number; readonly successCount: number; readonly successRate: number; readonly avgDurationMs: number; } declare const OrchestrateInputSchema: z.ZodObject<{ idempotencyKey: z.ZodOptional; dispatch: z.ZodOptional; mode: z.ZodOptional>; task: z.ZodString; context: z.ZodOptional>; maxIterations: z.ZodDefault>; timeout: z.ZodOptional; }, z.core.$strip>; type OrchestrateInput = z.infer; declare const OrchestrateOutputSchema: z.ZodObject<{ taskId: z.ZodString; analysis: z.ZodObject<{ taskId: z.ZodString; complexity: z.ZodNumber; taskType: z.ZodString; requirements: z.ZodArray; risks: z.ZodArray; needsDecomposition: z.ZodBoolean; approach: z.ZodString; estimatedEffort: z.ZodNumber; }, z.core.$strip>; routing: z.ZodOptional>; result: z.ZodUnknown; stepsCompleted: z.ZodNumber; metadata: z.ZodObject<{ durationMs: z.ZodNumber; tokensUsed: z.ZodNumber; tokensMeasured: z.ZodOptional; expertsUsed: z.ZodArray; timeoutReason: z.ZodOptional; }, z.core.$strip>; workerDispatchStatus: z.ZodOptional>; }, z.core.$strip>; type OrchestrateOutput = z.infer; interface OrchestrateDeps extends BaseMcpToolDeps { /** Pre-configured orchestrator instance (unified interface). */ orchestrator?: IOrchestrator; /** Model adapter for fallback orchestration path (Issue #827) */ modelAdapter?: IModelAdapter | undefined; /** MCP notifier for client-visible logging (Issue #974) */ notifier?: IMcpNotifier | undefined; /** * Durable, hash-chained audit logger (#4097). Its only reader was the * access-constraint deriver's ALS audit trail, deleted in #5108; nothing in * the orchestrate tool consumes it today. Kept because `OrchestrateDeps` is * published — dropping the member is a breaking change for the next major * (#6319). */ auditLogger?: IAuditLogger; } declare class OrchestrationError extends AgentError$1 { constructor(message: string, options?: { cause?: Error; context?: Record; }); } /** Error when orchestration is unavailable (no model adapter). Issue #554. */ declare class OrchestrationUnavailableError extends AgentError$1 { constructor(message: string, options?: { cause?: Error; context?: Record; }); } /** * Persistent OutcomeStore — JSONL-backed cross-session persistence. * * Extends the in-memory OutcomeStore with disk-backed append-only * JSONL storage. Hydrates on construction, appends on every write. * Corrupt lines are skipped with a warning (graceful degradation). * * @module orchestration/outcomes/outcome-store-persistence * (Source: Issue #1009 — Cross-session persistence) */ interface PersistentOutcomeStoreConfig extends OutcomeStoreConfig { /** Override the file path (useful for testing). */ readonly filePath?: string; /** Override the data directory (useful for testing). */ readonly dataDir?: string; } /** * OutcomeStore that persists entries to a JSONL file on disk. * * - Construction: hydrates from existing JSONL file (Zod-validates each line) * - Append: calls super.append() then appendFileSync one JSON line * - Corruption: bad lines are skipped with a warning log */ declare class PersistentOutcomeStore extends OutcomeStore { private readonly filePath; private readonly logger; constructor(config?: PersistentOutcomeStoreConfig, logger?: ILogger); /** Override append to persist each entry to disk. */ append(outcome: TaskOutcome$1): void; /** * Reclassify hydrated entries that lack a failureCategory. * Bounded: reclassifyAll() skips success outcomes and already-classified * entries, so only unclassified failures are processed (#1457). */ /** * Purge false failures from skipped workers on hydration (#1528). * These are 0ms non-success worker-* entries created before the * recording fix, representing routing decisions not real failures. */ private purgeSkippedOnHydrate; private reclassifyHydrated; private hydrate; /** Rewrite the JSONL file from in-memory state after reclassification. */ private rewriteFile; private persistLine; } /** * Adaptive Thresholds — Learning Loop (Issue #901, Phase 4) * * Pure function-based module that computes dynamic thresholds from * observed task outcomes. Replaces hardcoded baseline/maxBonus/coldStart * values with data-driven adjustments. * * @module orchestration/outcomes/adaptive-thresholds */ /** Direction of performance change over time. */ type Trend = 'improving' | 'declining' | 'stable'; /** Result of computing adaptive thresholds for a CLI+category pair. */ interface AdaptiveThresholdResult { /** Adjusted baseline success rate (default: 0.7). */ readonly baseline: number; /** Adjusted max bonus cap (default: 10). */ readonly maxBonus: number; /** Minimum samples before adjustment (always 10). */ readonly coldStart: number; /** Detected performance trend. */ readonly trend: Trend; /** Confidence in the result (0-1), based on sample size. */ readonly confidence: number; /** Number of outcomes used for computation. */ readonly sampleCount: number; } /** * Computes adaptive thresholds for a CLI+category pair from outcome data. * * Below cold start threshold: returns defaults with zero confidence. * Above threshold: adjusts baseline toward observed rate, scales max * bonus by confidence, and detects trend. */ declare function computeAdaptiveThresholds(store: OutcomeStore, cli: CliNameLiteral, category: TaskCategory): AdaptiveThresholdResult; /** * Detects performance trend by comparing recent vs historical success rates. * * Splits outcomes into two windows of `windowSize` (default 25). * If fewer than 2 * windowSize outcomes, uses half-split. */ declare function detectTrend(outcomes: readonly TaskOutcome$1[], windowSize?: number): Trend; /** * MCP tool for task orchestration with intelligent workflow pattern routing. * Types/schemas in orchestrate-types.ts (Issue #708). Routing via Issue #846. * @module mcp/tools/orchestrate */ /** * Registers the orchestrate tool with the MCP server. * Uses createSecureHandler (Issue #531) with timeout protection (Issue #271). * @category MCP */ declare function registerOrchestrateTool(server: McpServer, deps: OrchestrateDeps): void; /** * nexus-agents/cli-adapters - Budget Router Types * * Type definitions for budget-constrained routing based on PILOT pattern. * * @module cli-adapters/budget-router-types * (Source: Issue #102, arXiv:2401.02987) */ interface BanditContext { /** Task complexity score (0-1) */ readonly taskComplexity: number; /** Required context length normalized (0-1) */ readonly contextLengthNormalized: number; /** Is code generation task (0 or 1) */ readonly isCodeTask: number; /** Is reasoning task (0 to 1, supports fractional values) */ readonly isReasoningTask: number; /** Budget utilization (0-1) */ readonly budgetUtilization: number; /** Time pressure (0-1, higher = more urgent) */ readonly timePressure: number; } /** * LinUCB bandit configuration. */ interface LinUCBConfig { /** Number of arms (adapters) */ readonly numArms: number; /** Feature dimension */ readonly featureDim: number; /** Exploration parameter (higher = more exploration) */ readonly alpha: number; /** Regularization parameter */ readonly lambda: number; } /** * nexus-agents/learning - Outcome Feedback Types * * Type definitions for the closed-loop outcome feedback system * that enables continuous learning from routing decisions. * * @module learning/outcome-feedback-types * (Source: Issue #160, Alignment Roadmap Phase 2) */ /** * Router type that made the routing decision. * * NOTE: `'quality'` has no producer — `getDecisiveRouterType` cannot return it, * so `countDecisionsByRouter` reports `quality: 0` forever. It is not being * given a producer to justify its existence (#5812 panel: "do NOT invent a * producer — that is YAGNI backwards"). Removing a member of this union is a * breaking change, so `'quality'` is documented as unreachable here and removed * in the same next-major change that adds an `'unattributed'` member (#5914). * * No `@deprecated` tag: the tag applies to the whole type alias, and * `RouterType` itself is not deprecated — `no-deprecated` would then fire at * every one of its call sites for a defect in one member. */ type RouterType = 'linucb' | 'preference' | 'quality' | 'cascade' | 'topsis'; /** * Task outcome classification. */ type OutcomeClass = 'success' | 'partial' | 'failure' | 'timeout' | 'error'; /** * Quality signals extracted from task execution. */ interface QualitySignals { /** Whether code tests passed (for code tasks) */ readonly testsPass?: boolean | undefined; /** Number of lint errors (for code tasks) */ readonly lintErrors?: number | undefined; /** Explicit user approval/rejection */ readonly userApproved?: boolean | undefined; /** Number of retries required */ readonly retryCount: number; /** Task completion percentage (0-1) */ readonly completionRatio: number; /** Whether output was valid JSON/structured (for structured output tasks) */ readonly validStructure?: boolean | undefined; /** Response coherence score (0-1) */ readonly coherenceScore?: number | undefined; } /** * Zod schema for quality signals. */ declare const QualitySignalsSchema: z.ZodObject<{ testsPass: z.ZodOptional; lintErrors: z.ZodOptional; userApproved: z.ZodOptional; retryCount: z.ZodDefault; completionRatio: z.ZodDefault; validStructure: z.ZodOptional; coherenceScore: z.ZodOptional; }, z.core.$strip>; /** * Recorded routing decision for feedback tracking. */ interface RoutingDecision { /** Unique decision ID */ readonly id: string; /** Timestamp of decision */ readonly timestamp: string; /** Original query/task that was routed */ readonly query: string; /** Type of router used */ readonly routerType: RouterType; /** * Whether `routerType` was MEASURED or is a fallback label (#5812). * * `getDecisiveRouterType` tests four stage names and, when none of them * explains the decision, returns `'topsis'` — byte-identical to its own * measured `'topsis'` answer. `routerType` is therefore best-effort, and this * field is what qualifies it. * * Three states, deliberately: * - `true` — a stage was identified and `routerType` names it. * - `false` — no stage explained the decision; `routerType` is a fallback. * - absent — a row written before this field existed. Read it as UNMEASURED, * never as measured: a legacy row carries exactly as much evidence as the * fallback does. */ readonly routerTypeMeasured?: boolean | undefined; /** Selected model/adapter name */ readonly selectedModel: string; /** Selected model tier (strong/weak for preference routing) */ readonly selectedTier?: 'strong' | 'weak' | undefined; /** Arm index for LinUCB bandit */ readonly armIndex?: number | undefined; /** Bandit context (for LinUCB decisions) */ readonly banditContext?: BanditContext | undefined; /** Query features (for preference routing) */ readonly queryFeatures?: QueryFeatures | undefined; /** UCB score (for LinUCB) */ readonly ucbScore?: number | undefined; /** Confidence score */ readonly confidence?: number | undefined; /** Trace ID to correlate with SwarmObserver events */ readonly traceId: TraceId; /** Task domain classification */ readonly domain?: string | undefined; } /** * Zod schema for routing decision. */ declare const RoutingDecisionSchema: z.ZodObject<{ id: z.ZodUUID; timestamp: z.ZodISODateTime; query: z.ZodString; routerType: z.ZodEnum<{ quality: "quality"; cascade: "cascade"; topsis: "topsis"; linucb: "linucb"; preference: "preference"; }>; routerTypeMeasured: z.ZodOptional; selectedModel: z.ZodString; selectedTier: z.ZodOptional>; armIndex: z.ZodOptional; banditContext: z.ZodOptional>; queryFeatures: z.ZodOptional>; ucbScore: z.ZodOptional; confidence: z.ZodOptional; traceId: z.ZodString; domain: z.ZodOptional; }, z.core.$strip>; /** * Task outcome for a routing decision. */ interface TaskOutcome { /** Reference to the routing decision */ readonly routingDecisionId: string; /** Timestamp of outcome */ readonly timestamp: string; /** Outcome classification */ readonly outcomeClass: OutcomeClass; /** Overall success indicator */ readonly success: boolean; /** Quality score (0-1) */ readonly qualityScore: number; /** Execution duration in milliseconds */ readonly durationMs: number; /** Token usage */ readonly tokenUsage: number; /** Error message if failed */ readonly errorMessage?: string | undefined; /** Extracted quality signals */ readonly qualitySignals: QualitySignals; /** Trace ID for correlation */ readonly traceId: TraceId; } /** * Zod schema for task outcome. */ declare const TaskOutcomeSchema: z.ZodObject<{ routingDecisionId: z.ZodUUID; timestamp: z.ZodISODateTime; outcomeClass: z.ZodEnum<{ error: "error"; timeout: "timeout"; success: "success"; failure: "failure"; partial: "partial"; }>; success: z.ZodBoolean; qualityScore: z.ZodNumber; durationMs: z.ZodNumber; tokenUsage: z.ZodNumber; errorMessage: z.ZodOptional; qualitySignals: z.ZodObject<{ testsPass: z.ZodOptional; lintErrors: z.ZodOptional; userApproved: z.ZodOptional; retryCount: z.ZodDefault; completionRatio: z.ZodDefault; validStructure: z.ZodOptional; coherenceScore: z.ZodOptional; }, z.core.$strip>; traceId: z.ZodString; }, z.core.$strip>; /** * Computed reward for bandit update. */ interface ComputedReward { /** The reward value (0-1) */ readonly reward: number; /** Components that contributed to the reward */ readonly components: { readonly baseReward: number; readonly qualityBonus: number; readonly speedBonus: number; readonly efficiencyBonus: number; readonly retryPenalty: number; }; /** Explanation of reward computation */ readonly explanation: string; } /** * Feedback loop statistics. */ interface FeedbackLoopStats { /** Total routing decisions recorded */ readonly totalDecisions: number; /** Total outcomes recorded */ readonly totalOutcomes: number; /** Decisions pending outcome */ readonly pendingOutcomes: number; /** Outcomes by classification */ readonly outcomesByClass: Record; /** Average quality score */ readonly avgQualityScore: number; /** Average reward computed */ readonly avgReward: number; /** * Decisions by router type, counting ONLY decisions whose `routerType` was * measured (#5812). Before this, every unattributable decision was counted as * `topsis`, inflating the exact number this metric exists to report. */ readonly decisionsByRouter: Record; /** * Decisions whose routing stage could not be identified, and which therefore * appear in NO bucket of `decisionsByRouter` (#5812). * * This is the field that makes `routerTypeMeasured` a fix rather than an * annotation: without it the unattributable population would still have to * land somewhere, and "somewhere" was `topsis`. */ readonly decisionsUnattributed: number; /** Last update timestamp */ readonly lastUpdatedAt: string; } /** * Configuration for the feedback collector. */ interface FeedbackCollectorConfig { /** Maximum pending decisions to track */ readonly maxPendingDecisions: number; /** Timeout for pending decisions (ms) */ readonly pendingTimeoutMs: number; /** Enable automatic reward computation */ readonly enableAutoReward: boolean; /** Weight for quality in reward computation */ readonly qualityWeight: number; /** Weight for speed in reward computation */ readonly speedWeight: number; /** Weight for efficiency in reward computation */ readonly efficiencyWeight: number; /** Penalty per retry in reward computation */ readonly retryPenalty: number; /** Target duration for speed bonus (ms) */ readonly targetDurationMs: number; /** Target token usage for efficiency bonus */ readonly targetTokenUsage: number; /** Maximum history entries (outcomes + decisions) to retain */ readonly maxHistorySize: number; } /** * Default feedback collector configuration. */ declare const DEFAULT_FEEDBACK_COLLECTOR_CONFIG: FeedbackCollectorConfig; /** * Zod schema for feedback collector configuration. */ declare const FeedbackCollectorConfigSchema: z.ZodObject<{ maxPendingDecisions: z.ZodDefault; pendingTimeoutMs: z.ZodDefault; enableAutoReward: z.ZodDefault; qualityWeight: z.ZodDefault; speedWeight: z.ZodDefault; efficiencyWeight: z.ZodDefault; retryPenalty: z.ZodDefault; targetDurationMs: z.ZodDefault; targetTokenUsage: z.ZodDefault; maxHistorySize: z.ZodDefault; }, z.core.$strip>; /** * Interface for outcome feedback collector. */ interface IOutcomeFeedback { /** * Record a routing decision for tracking. */ recordRoutingDecision(decision: RoutingDecision): void; /** * Record an outcome for a routing decision. */ recordOutcome(outcome: TaskOutcome): void; /** * Process outcome for a trace ID (finds matching decision and computes reward). */ processOutcome(traceId: TraceId, outcome: Omit): void; /** * Compute reward from an outcome. */ computeReward(outcome: TaskOutcome): ComputedReward; /** * Get feedback loop statistics. */ getStats(): FeedbackLoopStats; /** * Get pending decisions (waiting for outcomes). */ getPendingDecisions(): readonly RoutingDecision[]; /** * Clear expired pending decisions. */ clearExpiredDecisions(): number; /** * Reset all state. */ reset(): void; } /** * Callback for when an outcome is processed. */ type OutcomeProcessedCallback = (decision: RoutingDecision, outcome: TaskOutcome, reward: ComputedReward) => void; /** * nexus-agents/cli-adapters - LinUCB Bandit * * Linear Upper Confidence Bound bandit for budget-aware model selection. * Implements the PILOT pattern for lazy budget allocation. * * @module cli-adapters/linucb-bandit * (Source: Issue #102, arXiv:2401.02987) */ /** * Per-arm × per-model warm-start replay statistic (#4194). * * The bandit's arms stay keyed by CLI slot / routing arm id — this is a * telemetry surface exposing which concrete models the replayed outcomes * came from, so per-model shadow evaluation can read the grouping without * changing arm structure or selection behavior. */ interface WarmStartModelStat { /** Arm the outcome was replayed into (outcome.cli). */ readonly arm: string; /** Concrete model id the outcome carried (outcome.model). */ readonly model: string; /** Number of outcomes replayed for this arm × model. */ readonly replayedCount: number; /** Number of those outcomes that were successes. */ readonly successCount: number; } /** * LinUCB bandit for contextual multi-armed bandit problem. */ declare class LinUCBBandit { private readonly config; private readonly arms; private readonly armNames; /** Warm-start replay ledger keyed `arm model` (#4194). Telemetry only. */ private readonly warmStartModelLedger; constructor(armNames: readonly string[], config?: Partial); /** * Select an arm given the context. * Returns arm index and UCB score. */ select(context: BanditContext): { armIndex: number; armName: string; ucbScore: number; }; /** * Update arm with observed reward. * Uses Sherman-Morrison formula for O(d²) incremental inverse update. * (Source: Issue #254, PILOT paper section 3.2) */ update(armIndex: number, context: BanditContext, reward: number): void; /** * Compute UCB score for an arm given features. * Uses cached AInv for O(d²) computation instead of O(d³) matrix inverse. */ private computeUCB; /** * Get arm names. */ getArmNames(): readonly string[]; /** * Get statistics for all arms. */ getStats(): ReadonlyArray<{ name: string; pullCount: number; avgReward: number; }>; /** * Get detailed statistics for all arms including learned weights. * Useful for debugging and ML observability. */ getDetailedStats(): ReadonlyArray<{ name: string; pullCount: number; avgReward: number; cumulativeReward: number; learnedWeights: readonly number[]; featureImportance: readonly { feature: string; importance: number; }[]; }>; /** * Get exploration statistics. */ getExplorationStats(): { totalPulls: number; explorationRatio: number; armDistribution: ReadonlyArray<{ name: string; proportion: number; }>; }; /** * Seed priors for cold-start improvement (Epic #952, Phase 6). * * Simulates `observationCount` synthetic observations per arm using * a neutral context and the provided reward hint. This gives arms * a head start based on known quality signals while still allowing * LinUCB exploration to override the seeded priors. * * @param priors - Map of arm name to initial reward hint (0-1) * @param observationCount - Number of synthetic observations (default: 5, max: 20) */ seedPriors(priors: ReadonlyMap, observationCount?: number): void; /** * Warm-start bandit from persisted task outcomes (Issue #1015). * * Replays historical outcomes through update() to reconstruct arm weights * from persisted data. Uses a neutral context (same as seedPriors) since * the original task context is not stored in TaskOutcome. * * Outcomes whose arm is not among this bandit's arms are skipped. That skip * used to be entirely silent, which hid a real defect: `api:*` arms could not * be represented in `TaskOutcome.cli` at all (#4400), so every API arm * discarded its whole history and began cold each process with nothing * reported. The skip is now counted and logged — a warm-start that silently * drops most of its input looks identical to one that worked. * * @param outcomes - Persisted task outcomes to replay * @returns Number of outcomes successfully replayed */ warmStart(outcomes: readonly TaskOutcome$1[]): number; /** Accumulate the per-arm × per-model warm-start ledger (#4194). */ private recordWarmStartModelStat; /** * Per-arm × per-model grouping of the outcomes replayed through * {@link warmStart} (#4194). A telemetry surface for per-model outcome * evaluation — arm structure and selection behavior are unchanged. * Sorted by arm, then model, for stable output. */ getWarmStartModelStats(): readonly WarmStartModelStat[]; /** * Reset all arm statistics. */ reset(): void; } /** * Preference Router Data Store * * In-memory storage for preference data points used by the PreferenceRouter. * * @module cli-adapters/preference-router-store * (Source: Issue #148, arXiv:2406.18665) */ /** * In-memory preference data store implementation. */ declare class InMemoryPreferenceStore implements IPreferenceDataStore { private readonly dataPoints; private readonly maxSize; constructor(maxSize?: number); store(dataPoint: PreferenceDataPoint): void; getAll(): readonly PreferenceDataPoint[]; getByDomain(domain: string): readonly PreferenceDataPoint[]; findSimilar(features: QueryFeatures, limit: number): readonly PreferenceDataPoint[]; getStats(): PreferenceModelStats; clear(): void; private calculateSimilarity; private enforceLimit; } /** * Preference Router Feature Extractor * * Extracts query features for preference-based routing decisions. * * @module cli-adapters/preference-router-extractor * (Source: Issue #148, arXiv:2406.18665) */ /** * Feature extractor for queries. */ declare class QueryFeatureExtractor { extract(query: string): QueryFeatures; private estimateTokens; private calculateComplexity; private hasKeywords; private countKeywords; private detectDomain; private generateKeywordSignature; } /** * nexus-agents/cli-adapters - Preference Router Implementation * * Implements preference-trained routing (RouteLLM pattern) that learns * from human preference data to route queries optimally. * * @module cli-adapters/preference-router * (Source: Issue #148, arXiv:2406.18665) */ /** * Preference-trained router that learns from human preference data. */ declare class PreferenceRouter { private readonly config; private readonly dataStore; private readonly featureExtractor; constructor(config?: Partial, dataStore?: IPreferenceDataStore); /** * Route a query to the optimal model based on learned preferences. */ route(query: string): PreferenceRoutingDecision; /** * Record a preference data point for online learning. */ recordPreference(query: string, strongModelPreferred: boolean, strongModelQuality?: number, weakModelQuality?: number): PreferenceDataPoint; /** * Get statistics about the learned preference model. */ getStats(): PreferenceModelStats; /** * Check if the router has enough data to make informed decisions. */ hasMinimumData(): boolean; private predict; private heuristicPrediction; private getDomainThreshold; private calculateCostSavings; private generateReason; } /** * Create a PreferenceRouter instance. */ declare function createPreferenceRouter(config?: Partial, dataStore?: IPreferenceDataStore): PreferenceRouter; /** * nexus-agents/learning - Outcome Feedback Helpers * * Helper functions for outcome feedback calculations and statistics. * * @module learning/outcome-feedback-helpers */ /** * Create a routing decision record. */ declare function createRoutingDecision(params: Omit): RoutingDecision; /** * Create a task outcome record. */ declare function createTaskOutcome(params: Omit): TaskOutcome; /** * nexus-agents/learning - Outcome Feedback Collector * * Collects routing decisions and outcomes to enable closed-loop learning. * Feeds results back to LinUCB and PreferenceRouter for adaptation. * * @module learning/outcome-feedback * (Source: Issue #160, Alignment Roadmap Phase 2) */ declare class OutcomeFeedbackCollector implements IOutcomeFeedback { private readonly config; private readonly pendingDecisions; private readonly outcomes; private readonly decisionHistory; private readonly callbacks; private linucbBandit?; private preferenceRouter?; constructor(config?: Partial); /** * Register LinUCB bandit for direct feedback. */ registerLinUCBBandit(bandit: LinUCBBandit): void; /** * Register PreferenceRouter for direct feedback. */ registerPreferenceRouter(router: PreferenceRouter): void; /** * Subscribe to outcome processed events. */ onOutcomeProcessed(callback: OutcomeProcessedCallback): () => void; recordRoutingDecision(decision: RoutingDecision): void; recordOutcome(outcome: TaskOutcome): void; processOutcome(traceId: TraceId, partialOutcome: Omit): void; computeReward(outcome: TaskOutcome): ComputedReward; getStats(): FeedbackLoopStats; getPendingDecisions(): readonly RoutingDecision[]; clearExpiredDecisions(): number; private trimHistory; reset(): void; private feedbackToRouters; private feedbackToLinUCB; private feedbackToPreferenceRouter; private notifyCallbacks; private findDecisionByRoutingId; private findOldestPendingDecision; private calculateAverageReward; } /** * Create an OutcomeFeedbackCollector instance. */ declare function createOutcomeFeedbackCollector(config?: Partial): OutcomeFeedbackCollector; /** * nexus-agents/learning - Outcome Storage Types * * Type definitions for SQLite-based outcome persistence. * Enables cross-session learning for routing optimization. * * @module learning/outcome-storage-types * (Source: Issue #188 - Outcome recording for routing ML feedback) */ /** * Error class for outcome storage operations. */ declare class OutcomeStorageError extends NexusError { constructor(message: string, options?: Partial; }, 'code'>>); } /** * Stored routing decision record. */ interface StoredRoutingDecision { readonly id: string; readonly traceId: string; readonly timestamp: string; readonly routerType: RouterType; readonly selectedModel: CliName; readonly alternativeModels: readonly CliName[]; readonly confidence: number; readonly reason: string; readonly taskProfile: Record; readonly requestId?: string | undefined; /** * Whether a router actually attributed this decision (#5915, closing the * third step of #5812). Absent on a decision read back from a row written * before the column existed, and absence reads as UNMEASURED everywhere — * a legacy row carries no more evidence than the fallback does. */ readonly routerTypeMeasured?: boolean | undefined; } /** * Stored task outcome record. */ interface StoredTaskOutcome { readonly routingDecisionId: string; readonly timestamp: string; readonly outcomeClass: OutcomeClass; readonly success: boolean; readonly qualityScore: number; readonly durationMs: number; readonly tokenUsage: number; readonly errorMessage?: string | undefined; } /** * Stored computed reward record. */ interface StoredReward { readonly routingDecisionId: string; readonly timestamp: string; readonly reward: number; readonly baseReward: number; readonly qualityBonus: number; readonly speedBonus: number; readonly efficiencyBonus: number; readonly retryPenalty: number; } /** * Aggregated model statistics from stored data. */ interface StoredModelStats { readonly model: CliName; readonly totalDecisions: number; readonly totalOutcomes: number; readonly avgReward: number; readonly avgQualityScore: number; readonly avgLatencyMs: number; readonly successRate: number; } /** * Interface for outcome storage implementations. */ interface IOutcomeStorage { /** * Store a routing decision. */ storeDecision(decision: StoredRoutingDecision): Promise>; /** * Store a task outcome. */ storeOutcome(outcome: StoredTaskOutcome): Promise>; /** * Store a computed reward. */ storeReward(reward: StoredReward): Promise>; /** * Get routing decision by ID. */ getDecision(id: string): Promise>; /** * Get outcome for a routing decision. */ getOutcome(routingDecisionId: string): Promise>; /** * Get aggregated statistics per model. */ getModelStats(): Promise>; /** * Get recent decisions for a model. */ getRecentDecisions(model: CliName, limit: number): Promise>; /** * Get decisions by request ID (for audit trail integration). */ getDecisionsByRequestId(requestId: string): Promise>; /** * Prune old records. */ prune(olderThan: Date): Promise>; /** * Get total record counts. */ getCounts(): Promise>; } /** * Configuration for SQLite outcome storage. */ interface OutcomeStorageConfig { /** Path to SQLite database file */ dbPath: string; /** Optional logger instance */ logger?: ILogger; /** Maximum records to retain (default: 100000) */ maxRecords?: number; /** Auto-prune interval in ms (default: 3600000 = 1 hour) */ autoPruneInterval?: number; } /** * Zod schema for OutcomeStorageConfig validation. */ declare const OutcomeStorageConfigSchema: z.ZodObject<{ dbPath: z.ZodString; maxRecords: z.ZodOptional; autoPruneInterval: z.ZodOptional; }, z.core.$strip>; /** * Default configuration values. */ declare const DEFAULT_OUTCOME_STORAGE_CONFIG: { readonly maxRecords: 100000; readonly autoPruneInterval: 3600000; }; /** * nexus-agents/learning - Feedback Integration Types * * Type definitions for feedback integration between routing and outcomes. * * @module learning/feedback-integration-types * (Source: Issue #167, Epic #164) */ /** * Parameters for recording an outcome. */ interface RecordOutcomeParams { /** Routing decision ID */ readonly routingDecisionId: string; /** Whether the task succeeded */ readonly success: boolean; /** Quality score (0-1) */ readonly qualityScore: number; /** Execution duration in milliseconds */ readonly durationMs: number; /** Token usage */ readonly tokenUsage: number; /** Number of retries (default: 0) */ readonly retryCount?: number | undefined; /** Trace ID for correlation */ readonly traceId?: TraceId | undefined; /** Error message for failed outcomes (sanitized before persistence) */ readonly errorMessage?: string | undefined; } /** * Configuration for feedback integration. */ interface FeedbackIntegrationConfig { /** Enable automatic feedback to routers (default: true) */ readonly enableAutoFeedback: boolean; /** Quality score threshold for success (default: 0.7) */ readonly successQualityThreshold: number; /** Quality score threshold for partial success (default: 0.4) */ readonly partialQualityThreshold: number; /** TTL for decision entries in milliseconds (default: 3600000 = 1 hour) */ readonly decisionTtlMs?: number | undefined; /** Logger instance */ readonly logger?: ILogger | undefined; /** * Enable persistent storage via SQLite (default: false). * Requires outcomeStorage to be provided. * (Source: Issue #560 - Wire SQLiteOutcomeStorage to feedback loop) */ readonly enablePersistence?: boolean | undefined; /** * SQLite outcome storage instance for cross-session learning. * Only used when enablePersistence is true. * (Source: Issue #560 - Wire SQLiteOutcomeStorage to feedback loop) */ readonly outcomeStorage?: IOutcomeStorage | undefined; } /** * Default configuration. */ declare const DEFAULT_FEEDBACK_INTEGRATION_CONFIG: FeedbackIntegrationConfig; /** * Interface for feedback integration. */ interface IFeedbackIntegration { /** Record a routing decision from CompositeRouter */ recordRoutingDecision(decision: CompositeRoutingDecision, traceId?: TraceId): string; /** Record a step outcome from workflow execution */ recordStepOutcome(routingDecisionId: string, stepResult: StepResult, durationMs: number, tokenUsage: number): void; /** Record a generic task outcome */ recordOutcome(params: RecordOutcomeParams): void; /** Get feedback statistics */ getStats(): FeedbackLoopStats; /** Subscribe to outcome processed events */ onOutcomeProcessed(callback: OutcomeProcessedCallback): () => void; /** Register CompositeRouter for bi-directional feedback */ registerCompositeRouter(router: ICompositeRouter): void; /** Reset all collected data */ reset(): void; /** Evict stale entries from decision map that exceed TTL */ evictStaleEntries(): number; /** Get total count of evicted entries since creation or last reset */ getEvictedEntryCount(): number; /** Get current size of decision map */ getDecisionMapSize(): number; } /** * nexus-agents/learning - Feedback Integration * * Connects OutcomeFeedbackCollector to workflow execution and CLI routing. * Enables closed-loop learning for routing decisions. * * @module learning/feedback-integration * (Source: Issue #167, Epic #164) */ declare class FeedbackIntegration implements IFeedbackIntegration { private readonly config; private readonly logger; private readonly collector; private compositeRouter?; /** SQLite storage for cross-session persistence (Issue #560) */ private readonly outcomeStorage?; private readonly decisionMap; private lastEvictionTime; private totalEvictedEntries; constructor(config?: Partial, collector?: OutcomeFeedbackCollector); recordRoutingDecision(decision: CompositeRoutingDecision, traceId?: TraceId): string; recordStepOutcome(routingDecisionId: string, stepResult: StepResult, durationMs: number, tokenUsage: number): void; recordOutcome(params: RecordOutcomeParams): void; /** Persists outcome and reward to SQLite storage (Issue #560). */ private persistOutcomeToStorage; getStats(): FeedbackLoopStats; onOutcomeProcessed(callback: OutcomeProcessedCallback): () => void; registerCompositeRouter(router: ICompositeRouter): void; reset(): void; /** * Evicts stale entries from decisionMap that exceed the configured TTL. * Called on every recordRoutingDecision (throttled) and on reset. */ evictStaleEntries(): number; /** * Gets the total number of evicted entries since creation or last reset. */ getEvictedEntryCount(): number; /** * Gets the current size of the decision map (for testing/monitoring). */ getDecisionMapSize(): number; private evictStaleEntriesThrottled; /** * Evicts the oldest N entries from the decision map by createdAt timestamp. * Used when the hard size cap is exceeded (Issue #666). */ private evictOldestEntries; private determineOutcomeClass; private computeStepQualityScore; private routeFeedbackToCompositeRouter; } /** * Creates a FeedbackIntegration instance. */ declare function createFeedbackIntegration(config?: Partial, collector?: OutcomeFeedbackCollector): IFeedbackIntegration; /** * Helper to compute reward from outcome. */ declare function computeOutcomeReward(collector: IOutcomeFeedback, outcome: TaskOutcome): ComputedReward; /** * nexus-agents/mcp - Delegate to Model Types * * Type definitions, schemas, and constants for model routing. * * @module mcp/tools/delegate-to-model-types * (Source: cli-project_plan.md v2.0.0) */ /** * Billing mode for model routing. * - 'plan': CLI adapters on monthly plans (cost is irrelevant, strongest model wins) * - 'api': Pay-per-token API usage (cost matters for routing decisions) */ type BillingMode = 'plan' | 'api'; /** * Preferred capability for task routing. */ type PreferredCapability = 'reasoning' | 'context' | 'speed' | 'code'; /** * Model capability profile for routing decisions. */ interface CapabilityProfile { /** Complex reasoning ability (0-10) */ readonly reasoning: number; /** Maximum context window in tokens */ readonly contextWindow: number; /** Code generation quality (0-10) */ readonly codeGeneration: number; /** Response latency score (0-10, higher = faster) */ readonly speed: number; /** Cost efficiency (0-10, higher = cheaper) */ readonly cost: number; } declare const MODEL_CAPABILITIES: Record; /** * Input schema for the delegate_to_model tool. */ declare const DelegateInputSchema: z.ZodObject<{ task: z.ZodString; preferred_capability: z.ZodOptional>; model_hint: z.ZodOptional; billing_mode: z.ZodOptional>; }, z.core.$strip>; type DelegateInput = z.infer; /** * Output schema for the delegate_to_model tool response. */ declare const DelegateOutputSchema: z.ZodObject<{ recommended_model: z.ZodString; reasoning: z.ZodString; capabilities: z.ZodObject<{ reasoning: z.ZodNumber; contextWindow: z.ZodNumber; codeGeneration: z.ZodNumber; speed: z.ZodNumber; cost: z.ZodNumber; }, z.core.$strip>; estimated_tokens: z.ZodNumber; alternatives: z.ZodArray>; governance: z.ZodOptional>; }, z.core.$strip>; type DelegateOutput = z.infer; /** * Dependencies for the delegate_to_model tool. */ interface DelegateDeps extends BaseMcpToolDeps { /** Optional CompositeRouter for intelligent routing (Issue #169) */ router?: ICompositeRouter | undefined; /** Optional FeedbackIntegration for closed-loop learning (Issue #167) */ feedbackIntegration?: IFeedbackIntegration | undefined; /** MCP notifier for client-visible logging (Issue #974) */ notifier?: IMcpNotifier | undefined; } /** * Analyzes task to determine requirements. */ interface TaskRequirements { estimatedTokens: number; needsReasoning: boolean; needsLargeContext: boolean; needsSpeed: boolean; needsCodeGen: boolean; isCostSensitive: boolean; /** Whether the task requires image generation output (Issue #685) */ needsImageGen: boolean; /** Whether the task requires audio output (Issue #685) */ needsAudioOutput: boolean; /** Whether the task requires MCP tool support (Issue #685) */ needsMcp: boolean; /** Whether the task is exploration/research (benefits from large context) (Issue #807) */ needsExploration: boolean; } /** * nexus-agents/mcp - Delegate to Model Helpers * * Helper functions for task analysis and model selection. * * @module mcp/tools/delegate-to-model-helpers */ /** * Analyzes a task string to determine requirements. */ declare function analyzeTask(task: string): TaskRequirements; /** Selection result type. */ type SelectionResult = { model: string; reasoning: string; alternatives: Array<{ model: string; score: number; tradeoff: string; }>; }; /** * Selects the optimal model for a task. */ declare function selectModel(input: DelegateInput, requirements: TaskRequirements, billingMode?: BillingMode): SelectionResult; /** * nexus-agents/consensus/decision - Voting thresholds * * The numeric bars a tally is measured against. Extracted from * `consensus/types-core.ts` and `mcp/tools/consensus-vote-types.ts` (#6000 * step 1) so the constants that decide what "approved" means live in a module * that can be governed on its own path, apart from the routine types and * schemas they used to share a file with. Every previous home re-exports * these, so the public API is unchanged. * * @module consensus/decision/thresholds */ /** * Voting thresholds for each algorithm. */ declare const VOTING_THRESHOLDS: Record; /** * nexus-agents/consensus - Multi-Round Voting Protocol Types * * Multi-Round Voting Protocol Types (Issue #100) * Based on arXiv:2512.21352 - Multi-Agent Committees for Code Review */ /** * Voting round phases. * - analysis: Independent analysis (Round 1) * - deliberation: Share findings and discuss (Round 2) * - consensus: Final vote on recommendations (Round 3) */ declare const VotingRoundPhaseSchema: z.ZodEnum<{ analysis: "analysis"; consensus: "consensus"; deliberation: "deliberation"; }>; type VotingRoundPhase = z.infer; /** * Voting round status. */ declare const VotingRoundStatusSchema: z.ZodEnum<{ aborted: "aborted"; completed: "completed"; pending: "pending"; in_progress: "in_progress"; awaiting_votes: "awaiting_votes"; }>; type VotingRoundStatus = z.infer; /** * A finding submitted by an agent during analysis. */ declare const AgentFindingSchema: z.ZodObject<{ agentId: z.ZodString; category: z.ZodEnum<{ security: "security"; documentation: "documentation"; performance: "performance"; design: "design"; other: "other"; bug: "bug"; style: "style"; }>; severity: z.ZodEnum<{ critical: "critical"; major: "major"; minor: "minor"; suggestion: "suggestion"; }>; description: z.ZodString; location: z.ZodOptional; suggestion: z.ZodOptional; confidence: z.ZodNumber; timestamp: z.ZodOptional; }, z.core.$strip>; type AgentFinding = z.infer; /** * Finding vote during deliberation. */ declare const FindingVoteSchema: z.ZodObject<{ agentId: z.ZodString; findingId: z.ZodString; agree: z.ZodBoolean; reasoning: z.ZodOptional; amendedSeverity: z.ZodOptional>; }, z.core.$strip>; type FindingVote = z.infer; /** * A single voting round in the protocol. */ interface VotingRound { id: string; phase: VotingRoundPhase; status: VotingRoundStatus; findings: Map; findingVotes: Map; finalVotes: Map; startedAt: string; completedAt?: string; roundNumber: number; } /** * Configuration for the voting protocol. */ interface VotingProtocolConfig { /** Number of agents in the committee (default: 3) */ committeeSize: number; /** Maximum rounds before forcing decision (default: 3) */ maxRounds: number; /** Timeout per round in milliseconds (default: multi-llm-panel guard, 900000) */ roundTimeoutMs: number; /** Minimum agreement threshold (default: 2/3, approximately 0.667) */ agreementThreshold: number; /** Enable anti-sycophancy detection (default: true) */ enableAntiSycophancy: boolean; /** Similarity threshold for sycophancy detection (default: 0.8) */ sycophancyThreshold: number; } declare const VotingProtocolConfigSchema: z.ZodObject<{ committeeSize: z.ZodDefault; maxRounds: z.ZodDefault; roundTimeoutMs: z.ZodDefault; agreementThreshold: z.ZodDefault; enableAntiSycophancy: z.ZodDefault; sycophancyThreshold: z.ZodDefault; }, z.core.$strip>; declare const DEFAULT_VOTING_PROTOCOL_CONFIG: VotingProtocolConfig; /** * Session state for a voting protocol instance. */ interface VotingSession { id: string; topic: string; committee: string[]; rounds: VotingRound[]; currentRound: number; config: VotingProtocolConfig; status: 'active' | 'completed' | 'aborted'; createdAt: string; completedAt?: string; finalResult?: VotingProtocolResult; } /** * Final result of a voting protocol session. */ interface VotingProtocolResult { sessionId: string; topic: string; outcome: 'approved' | 'rejected' | 'needs_revision' | 'no_consensus'; consolidatedFindings: ConsolidatedFinding[]; roundSummaries: RoundSummary[]; agreementScore: number; sycophancyDetected: boolean; totalDurationMs: number; participatingAgents: string[]; } /** * A consolidated finding after deliberation. */ interface ConsolidatedFinding { id: string; category: AgentFinding['category']; severity: AgentFinding['severity']; description: string; location?: string; suggestion?: string; supportingAgents: string[]; agreementRatio: number; originalFindings: AgentFinding[]; } /** * Summary of a single round. */ interface RoundSummary { roundNumber: number; phase: VotingRoundPhase; findingsCount: number; votesCount: number; agreementScore: number; durationMs: number; } /** * Interface for the multi-round voting protocol. * (Source: Issue #100, arXiv:2512.21352) */ interface IVotingProtocol { /** Create a new voting session with a committee */ createSession(topic: string, committee: string[], config?: Partial): VotingSession; /** Start the analysis round (Round 1) */ startAnalysisRound(sessionId: string): Promise; /** Submit findings from an agent during analysis */ submitFindings(sessionId: string, agentId: string, findings: AgentFinding[]): Promise; /** Start the deliberation round (Round 2) */ startDeliberationRound(sessionId: string): Promise; /** Vote on findings during deliberation */ voteOnFinding(sessionId: string, vote: FindingVote): Promise; /** Start the consensus round (Round 3) */ startConsensusRound(sessionId: string): Promise; /** Submit final vote during consensus */ submitFinalVote(sessionId: string, agentId: string, vote: Vote): Promise; /** Get the final result (closes session if complete) */ getResult(sessionId: string): Promise; /** Check for sycophancy in the current round */ detectSycophancy(sessionId: string): SycophancyReport; /** Get the current session state */ getSession(sessionId: string): VotingSession | undefined; } /** * Report from sycophancy detection. */ interface SycophancyReport { detected: boolean; confidenceScore: number; indicators: SycophancyIndicator[]; affectedAgents: string[]; recommendation: string; } /** * Individual sycophancy indicator. */ interface SycophancyIndicator { type: 'premature_consensus' | 'opinion_convergence' | 'confidence_inflation' | 'echo_chamber'; description: string; severity: 'low' | 'medium' | 'high'; agents: string[]; } /** * nexus-agents/consensus - Weighted Byzantine Voting Types * * Weighted Byzantine Voting Types (Issue #103) * Based on CP-WBFT (arXiv:2511.10400) */ /** * Task outcome STATUS for tracking agent performance — a 4-state vote status, * NOT an outcome row. Named `*Status` to avoid colliding with the canonical * outcome *record* `TaskOutcome` in orchestration/outcomes (#3146/#3226: the * two were unrelated types that happened to share the name `TaskOutcome`). */ declare const TaskOutcomeStatusSchema: z.ZodEnum<{ unknown: "unknown"; success: "success"; failure: "failure"; partial: "partial"; }>; type TaskOutcomeStatus = z.infer; /** * Extended agent performance with Byzantine detection. */ interface WeightedAgentRecord { readonly agentId: string; readonly totalTasks: number; readonly successfulTasks: number; readonly failedTasks: number; readonly partialTasks: number; readonly successRate: number; readonly weight: number; readonly trustScore: number; readonly byzantineFlags: number; readonly lastActive: Date; readonly createdAt: Date; } /** * Weighted consensus result. */ interface WeightedConsensusResult { readonly decision: 'approve' | 'reject' | 'no_consensus'; readonly weightedApproval: number; readonly weightedRejection: number; readonly totalWeight: number; readonly quorumReached: boolean; readonly byzantineDetected: boolean; readonly participatingAgents: readonly string[]; readonly weightBreakdown: ReadonlyMap; } /** * Configuration for weighted Byzantine voting. */ interface WeightedVotingConfig { /** Minimum weight to participate in voting (default: 0.1) */ readonly minWeight: number; /** Maximum Byzantine fault tolerance (default: 0.33) */ readonly maxByzantineFraction: number; /** Weight decay factor per failed task (default: 0.9) */ readonly weightDecayFactor: number; /** Weight recovery factor per successful task (default: 1.05) */ readonly weightRecoveryFactor: number; /** Trust score required to vote (default: 0.3) */ readonly minTrustScore: number; /** Byzantine flag threshold for exclusion (default: 3) */ readonly byzantineFlagThreshold: number; /** Initial weight for new agents (default: 0.5) */ readonly initialWeight: number; /** Quorum threshold for valid consensus (default: 2/3, approximately 0.667) */ readonly quorumThreshold: number; } declare const DEFAULT_WEIGHTED_VOTING_CONFIG: WeightedVotingConfig; /** * Interface for weighted Byzantine voting. * (Source: Issue #103, arXiv:2511.10400 - CP-WBFT) */ interface IWeightedVoting { /** Calculate vote weight for an agent */ calculateWeight(agentId: string): number; /** Update agent performance based on task outcome */ updatePerformance(agentId: string, outcome: TaskOutcomeStatus): void; /** Run weighted consensus on votes */ weightedConsensus(votes: ReadonlyMap): WeightedConsensusResult; /** Register a new agent */ registerAgent(agentId: string): void; /** Get agent performance record */ getAgentRecord(agentId: string): WeightedAgentRecord | undefined; /** Flag agent for Byzantine behavior */ flagByzantine(agentId: string, reason: string): void; /** Get all agent records */ getAllRecords(): readonly WeightedAgentRecord[]; /** Check if agent can vote */ canVote(agentId: string): boolean; /** Recalibrate all weights based on global performance */ recalibrateWeights(): void; } /** * nexus-agents/consensus - Higher-Order Voting Types * * Type definitions for Opinion-Wise (OW) and Independent Subset Partition (ISP) * voting methods that account for correlations between agent opinions. * * Higher-order voting uses Bayesian-optimal aggregation that handles correlated * agents better than traditional independent voting assumptions. * * @module consensus/higher-order-types * (Source: Issue #333) */ /** * Pair of agent IDs for correlation tracking. * Stored as "agentA:agentB" where agentA < agentB lexicographically. */ type AgentPairKey = `${string}:${string}`; /** * Creates a canonical agent pair key for correlation lookup. * Orders agents lexicographically to ensure consistent keys. */ declare function createAgentPairKey(agentA: string, agentB: string): AgentPairKey; /** * Extracts agent IDs from a pair key. */ declare function parseAgentPairKey(key: AgentPairKey): [string, string]; /** * Correlation coefficient between two agents' voting patterns. * Range: -1 (perfectly anti-correlated) to +1 (perfectly correlated). * 0 indicates independence. */ declare const CorrelationCoefficientSchema: z.ZodNumber; type CorrelationCoefficient = z.infer; /** * Correlation matrix storing pairwise correlations between agents. */ type CorrelationMatrix = Map; /** * A subset of agents that vote independently of each other. * Used in ISP (Independent Subset Partition) method. */ interface IndependentSubset { /** Unique identifier for this subset */ readonly id: string; /** Agent IDs in this independent subset */ readonly agentIds: readonly string[]; /** * Average internal independence score (lower = more independent). * * Averaged over the pairs that HAVE a correlation, so read it together with * {@link pairCoverage}: a subset whose pairs were measured at 0 and one whose * pairs were never observed both score 0, and 0 is the score that earns the * maximum posterior weight. */ readonly independenceScore: number; /** * How many of the subset's agent pairs actually had a correlation, out of how * many exist. * * `observed < total` means {@link independenceScore} is an average over a * subset of the pairs — the unobserved ones contributed nothing rather than * being represented as unknown. A singleton has `total: 0`: there is no pair * to observe, so its score is not a measurement at all. */ readonly pairCoverage: { readonly observed: number; readonly total: number; }; /** Number of observations supporting this grouping */ readonly observationCount: number; } declare const IndependentSubsetSchema: z.ZodObject<{ id: z.ZodString; agentIds: z.ZodArray; independenceScore: z.ZodNumber; pairCoverage: z.ZodObject<{ observed: z.ZodNumber; total: z.ZodNumber; }, z.core.$strip>; observationCount: z.ZodNumber; }, z.core.$strip>; /** * Record of a single voting observation for correlation tracking. */ interface VotingObservation { /** Unique proposal ID */ readonly proposalId: string; /** Agent who cast the vote */ readonly agentId: string; /** The vote decision */ readonly decision: VoteDecision$1; /** Confidence level (0-1) */ readonly confidence: number; /** Whether the vote aligned with the final outcome */ readonly alignedWithOutcome: boolean; /** Timestamp of the vote */ readonly timestamp: Date; /** Pinned model identity used to select the correlation partition. */ readonly modelKey?: string; /** Model that actually answered, retained for provenance only. */ readonly observedModel?: string; } declare const VotingObservationSchema: z.ZodObject<{ proposalId: z.ZodString; agentId: z.ZodString; decision: z.ZodEnum<{ approve: "approve"; reject: "reject"; abstain: "abstain"; }>; confidence: z.ZodNumber; alignedWithOutcome: z.ZodBoolean; timestamp: z.ZodDate; modelKey: z.ZodOptional; observedModel: z.ZodOptional; }, z.core.$strip>; /** Model identities associated with one correlation-recording operation. */ interface CorrelationRecordContext { /** Role-to-pinned-model map used for correlation partition selection. */ readonly modelPins: ReadonlyMap; /** Role-to-serving-model map retained only as observation provenance. */ readonly observedModels?: ReadonlyMap; } /** * Aggregated voting history for a pair of agents. */ interface PairwiseVotingHistory { /** Agent pair key */ readonly pairKey: AgentPairKey; /** Number of proposals where both agents voted */ readonly jointObservations: number; /** Number of times both agents agreed */ readonly agreements: number; /** Number of times agents disagreed */ readonly disagreements: number; /** Computed correlation coefficient */ readonly correlation: CorrelationCoefficient; /** Last update timestamp */ readonly lastUpdated: Date; } declare const PairwiseVotingHistorySchema: z.ZodObject<{ pairKey: z.ZodType; jointObservations: z.ZodNumber; agreements: z.ZodNumber; disagreements: z.ZodNumber; correlation: z.ZodNumber; lastUpdated: z.ZodDate; }, z.core.$strip>; /** * Configuration for higher-order voting. * Correlation aggregates are lifetime evidence; retained records are count-bounded * by `maxProposals` FIFO and `maxObservationsPerAgent`, and active history is * partitioned by each role's pinned model. The legacy correlation lifetime keys * are deprecated and ignored. */ interface HigherOrderVotingConfig { /** Minimum observations before using correlation data (default: 10) */ readonly minObservationsForCorrelation: number; /** Correlation threshold to consider agents correlated (default: 0.3) */ readonly correlationThreshold: number; /** * @deprecated Ignored since 8.x: correlation evidence is lifetime and partitioned by the role's pinned model (#5555); nothing reads this value. Removed in the next major (#5564). */ readonly correlationMaxAgeMs: number; /** Independence threshold for ISP grouping (default: 0.2) */ readonly independenceThreshold: number; /** Whether to fall back to simple voting when correlation data insufficient */ readonly fallbackToSimpleVoting: boolean; /** * @deprecated Ignored since 8.x: correlation evidence is lifetime and partitioned by the role's pinned model (#5555); nothing reads this value. Removed in the next major (#5564). */ readonly observationDecayFactor: number; /** Maximum observations to store per agent before FIFO eviction (default: 1000) */ readonly maxObservationsPerAgent: number; /** Maximum total proposals to track before evicting oldest (default: 5000) */ readonly maxProposals: number; /** Maximum pairwise history entries before LRU eviction (default: 100) */ readonly maxTrackedPairs: number; } declare const HigherOrderVotingConfigSchema: z.ZodObject<{ minObservationsForCorrelation: z.ZodDefault; correlationThreshold: z.ZodDefault; correlationMaxAgeMs: z.ZodDefault; independenceThreshold: z.ZodDefault; fallbackToSimpleVoting: z.ZodDefault; observationDecayFactor: z.ZodDefault; maxObservationsPerAgent: z.ZodDefault; maxProposals: z.ZodDefault; maxTrackedPairs: z.ZodDefault; }, z.core.$strip>; declare const DEFAULT_HIGHER_ORDER_CONFIG: HigherOrderVotingConfig; /** * Result of Bayesian aggregation with correlation awareness. */ interface HigherOrderVotingResult { /** Final decision */ readonly decision: 'approve' | 'reject' | 'no_consensus'; /** Posterior probability of approval */ readonly posteriorApproval: number; /** Posterior probability of rejection */ readonly posteriorRejection: number; /** Effective number of independent votes */ readonly effectiveVoteCount: number; /** Whether correlation data was sufficient */ readonly usedCorrelationData: boolean; /** Method used: 'ow' (opinion-wise), 'isp', or 'simple' (fallback) */ readonly method: 'ow' | 'isp' | 'simple'; /** Improvement over baseline majority voting (percentage points) */ readonly improvementOverBaseline: number; /** Independent subsets used (if ISP method) */ readonly independentSubsets?: readonly IndependentSubset[]; /** Agents whose votes were down-weighted due to correlation */ readonly downweightedAgents: readonly string[]; /** Reasoning for the decision */ readonly reasoning: string; } declare const HigherOrderVotingResultSchema: z.ZodObject<{ decision: z.ZodEnum<{ approve: "approve"; reject: "reject"; no_consensus: "no_consensus"; }>; posteriorApproval: z.ZodNumber; posteriorRejection: z.ZodNumber; effectiveVoteCount: z.ZodNumber; usedCorrelationData: z.ZodBoolean; method: z.ZodEnum<{ simple: "simple"; ow: "ow"; isp: "isp"; }>; improvementOverBaseline: z.ZodNumber; independentSubsets: z.ZodOptional; independenceScore: z.ZodNumber; pairCoverage: z.ZodObject<{ observed: z.ZodNumber; total: z.ZodNumber; }, z.core.$strip>; observationCount: z.ZodNumber; }, z.core.$strip>>>; downweightedAgents: z.ZodArray; reasoning: z.ZodString; }, z.core.$strip>; /** * Statistics about correlation tracking. */ interface CorrelationTrackerStats { /** Total agents being tracked */ readonly totalAgents: number; /** Total agent pairs with correlation data */ readonly trackedPairs: number; /** Total voting observations recorded */ readonly totalObservations: number; /** Average correlation across all pairs */ readonly averageCorrelation: number; /** Number of identified independent subsets */ readonly independentSubsetCount: number; /** Pairs with sufficient data for correlation calculation */ readonly pairsWithSufficientData: number; } declare const CorrelationTrackerStatsSchema: z.ZodObject<{ totalAgents: z.ZodNumber; trackedPairs: z.ZodNumber; totalObservations: z.ZodNumber; averageCorrelation: z.ZodNumber; independentSubsetCount: z.ZodNumber; pairsWithSufficientData: z.ZodNumber; }, z.core.$strip>; /** * Interface for correlation tracking between agents. */ interface ICorrelationTracker { /** Select the active model partition for each pinned role. */ setCurrentModelPins?(modelPins: ReadonlyMap): void; /** * Record a vote and its outcome for correlation tracking. */ recordVote(agentId: string, vote: Vote, outcome: 'approved' | 'rejected', context?: CorrelationRecordContext): void; /** * Record votes from multiple agents for the same proposal. */ recordProposalVotes(proposalId: string, votes: ReadonlyMap, outcome: 'approved' | 'rejected', context?: CorrelationRecordContext): void; /** * Compute the full correlation matrix for all tracked agents. */ computeCorrelationMatrix(): CorrelationMatrix; /** * Get correlation between two specific agents. * Returns undefined if insufficient data. */ getCorrelation(agentA: string, agentB: string): CorrelationCoefficient | undefined; /** * Identify groups of agents that vote independently. */ identifyIndependentSubsets(): readonly IndependentSubset[]; /** * Check if there is sufficient correlation data for a set of agents. */ hasSufficientData(agentIds: readonly string[]): boolean; /** * Get statistics about the correlation tracker. */ getStats(): CorrelationTrackerStats; /** * Clear all recorded data. */ clear(): void; } /** * Interface for Opinion-Wise higher-order voting. */ interface IHigherOrderVoting { /** * Aggregate votes using Bayesian correlation-aware method. */ aggregateWithCorrelation(votes: ReadonlyMap, correlationMatrix: CorrelationMatrix): HigherOrderVotingResult; /** * Estimate correlation matrix from voting history. */ estimateCorrelation(tracker: ICorrelationTracker): CorrelationMatrix; /** * Compute result using Independent Subset Partition method. */ computeISP(votes: ReadonlyMap, independentSubsets: readonly IndependentSubset[]): HigherOrderVotingResult; /** * Full pipeline: estimate correlation, compute result. * * `tracker` is OPTIONAL (#3173): when omitted, the instance uses the tracker * injected at construction (`OWVotingOptions.tracker`), letting higher-order * voting be reused as a building block without threading the tracker through * every call. A per-call `tracker` still wins. Throws if neither is available. */ aggregate(votes: ReadonlyMap, tracker?: ICorrelationTracker): HigherOrderVotingResult; /** * Get the current configuration. */ getConfig(): HigherOrderVotingConfig; } /** * nexus-agents/consensus/decision - Verdict computation * * The pure functions that turn a tally into a decision, extracted verbatim * (#6000 step 1) from the three files that used to hold them: * * - `evaluateThreshold` (from `consensus/strategies.ts`): ratio vs. bar — the * comparison behind the simple-majority, supermajority and proof-of-learning * strategies. * - `determineFinalStatus` (from `consensus/result-builder.ts`): quorum + * approval → the engine's `approved` / `rejected`. * - `mapOutcomeToDecision`, `resolveVoteDecision` and its helpers (from * `mcp/tools/consensus-vote-types.ts`): engine outcome + error policy → * the response-layer `approved` / `rejected` / `no_quorum`. * * What stays outside: the strategy classes that count votes and call * `evaluateThreshold` (`strategies.ts`), the engine's cascade and close * orchestration (`engine.ts`), the error-policy vote-list shaping that feeds * the engine (`consensus-vote-error-policy.ts`), and the response assembly in * `buildResponse`. Each previous home re-exports what moved, so the public * API is unchanged. Types from the MCP tool module are imported type-only, so * this module has no runtime edge into `mcp/`. * * @module consensus/decision/verdict */ /** * Determine final status based on quorum and approval. */ declare function determineFinalStatus(quorumReached: boolean, approved: boolean): ProposalStatus; /** * nexus-agents/mcp - Delegate to Model Tool * * MCP tool for capability-matched task routing. * Routes tasks to optimal model based on task requirements and available capacity. * Supports intelligent routing via CompositeRouter when available. * * @module mcp/tools/delegate-to-model * (Source: MCP Protocol 2025-11-25) * (Source: cli-project_plan.md v2.0.0) * (Source: Issue #169, Epic #164) * (Refactored: Issue #531 - Use createSecureHandlerFactory) */ /** * Registers the delegate_to_model tool with the MCP server. * * Uses createSecureHandler for standardized security middleware (Issue #531). * Includes timeout protection for CVE-2026-0621 mitigation (Issue #271). * * @category MCP * @param server - MCP server instance * @param deps - Dependencies */ declare function registerDelegateToModelTool(server: McpServer, deps: DelegateDeps): void; /** * nexus-agents/orchestration - Checkpoint Types * * Type definitions for durable execution checkpointing. * Enables crash recovery, human-in-the-loop pause/resume, * and execution replay for debugging. * * @module orchestration/graph/checkpoint-types * (Source: Issue #833 — Orchestrator checkpointing) */ /** * Captures a paused-execution context when a node returns an Interrupt. * Persisted alongside the checkpoint so the resume() caller can read the * value the node surfaced and supply a matching `{[id]: resumeValue}` map. */ interface CheckpointInterrupt { /** Node that returned the interrupt — re-runnable as the first step on resume. */ readonly nodeId: string; /** Stable interrupt id from the Interrupt envelope. */ readonly interruptId: string; /** Value the node surfaced for the human. */ readonly value: unknown; /** ISO timestamp when the interrupt fired. */ readonly createdAt: string; /** * ISO timestamp when this interrupt was consumed by a successful * resumeFromCheckpoint() call. A second resume against the same checkpoint * is rejected — see #2425 idempotency requirement. */ readonly consumedAt?: string; /** * Additional interrupts dropped because they fired in the same super-step * as the primary one (#2425 multi-interrupt observability). Phase 1 * silently dropped these; Phase 2 surfaces them so operators can detect * lost human-input requests in the wild. The executor still only honors * the primary interrupt; downstream tooling can fan out from this list. */ readonly additionalInterrupts?: readonly { readonly nodeId: string; readonly interruptId: string; readonly value: unknown; }[]; } /** Schema version for forward compatibility. */ declare const CHECKPOINT_SCHEMA_VERSION = 1; /** * A snapshot of graph execution state at a given step boundary. * Contains all information needed to resume execution. */ interface Checkpoint { /** Unique checkpoint ID. */ readonly id: string; /** Execution ID this checkpoint belongs to. */ readonly executionId: string; /** Schema version for deserialization. */ readonly schemaVersion: number; /** Step number when this checkpoint was taken. */ readonly stepNumber: number; /** Full graph state at this point. */ readonly state: Readonly; /** IDs of nodes ready to run next. */ readonly pendingNodeIds: readonly string[]; /** Results of all completed nodes so far. */ readonly completedResults: readonly NodeResult[]; /** ISO timestamp when checkpoint was created. */ readonly createdAt: string; /** Optional metadata for debugging. */ readonly metadata?: Record | undefined; /** * If present, the checkpoint was created because a node returned an * Interrupt. The resume API uses this to know which node to re-run and * which interrupt id to match resume values against. (#1895) */ readonly interrupt?: CheckpointInterrupt | undefined; } /** * Summary of a checkpoint (for listing without full state). */ interface CheckpointSummary { readonly id: string; readonly executionId: string; readonly stepNumber: number; readonly createdAt: string; readonly completedNodeCount: number; readonly pendingNodeCount: number; } /** * Abstract checkpoint store interface. * Implementations provide persistence (in-memory, JSON file, SQLite, etc.). */ interface ICheckpointStore { /** Saves a checkpoint. Overwrites if ID already exists. */ save(checkpoint: Checkpoint): void; /** Loads a checkpoint by ID. Returns undefined if not found. */ load(id: string): Checkpoint | undefined; /** Loads the latest checkpoint for a given execution ID. */ latest(executionId: string): Checkpoint | undefined; /** Lists all checkpoint summaries for a given execution ID. */ list(executionId: string): readonly CheckpointSummary[]; /** Deletes a checkpoint by ID. Returns true if found and deleted. */ delete(id: string): boolean; /** Deletes all checkpoints for a given execution ID. */ deleteExecution(executionId: string): number; /** Returns total number of checkpoints across all executions. */ size(): number; /** Clears all checkpoints. */ clear(): void; } /** * nexus-agents/orchestration - Graph Workflow Types * * Type definitions for graph-based workflow orchestration inspired by * LangGraph's StateGraph pattern. Enables DAG-based workflows with * conditional edges, typed state reducers, and fan-out/fan-in. * * @module orchestration/graph/graph-types * (Source: Issue #831 — Graph-based workflow orchestration) */ /** * Context passed to node hooks (preconditions and verification). * Provides read-only access to current execution state. */ interface NodeHookContext { readonly nodeId: string; readonly state: Readonly; readonly stepNumber: number; } /** * Error type for hook failures — identifies which hook failed and why. */ interface HookError { readonly hookName: string; readonly nodeId: string; readonly message: string; } /** * Hook function signature. Returns ok(void) on success, err(HookError) on failure. */ type NodeHook = (ctx: NodeHookContext) => Promise>; /** * Configuration for a precondition hook. * Preconditions run before node execution. * If a required precondition fails, the node is skipped. */ interface PreconditionConfig { readonly name: string; readonly hook: NodeHook; /** If true (default), failure prevents node execution. */ readonly required?: boolean | undefined; } /** * State reducer controls how values merge when multiple nodes write * to the same state field. Inspired by LangGraph's Annotated reducers. */ type StateReducer = { type: 'overwrite'; } | { type: 'append'; } | { type: 'custom'; merge: (existing: T, incoming: T) => T; }; /** * Schema entry for a single state field — name, default, and merge strategy. */ interface StateFieldSchema { readonly defaultValue: T; readonly reducer: StateReducer; } /** * State schema defines all fields and their reducers. */ type StateSchema = Record; /** * Flattened state values at runtime (one value per field). */ type GraphState = Record; /** * Marks a deliberate pause in graph execution. Returned (or thrown) by a node * to halt the super-step loop and surface `value` to a human. Resumption is * keyed by `id`: the caller provides `{[id]: resumeValue}` to * `resumeFromCheckpoint(...)`, and the value is delivered to the same node via * its NodeContext on the next run. * * Modeled on langchain-ai/langgraph's Interrupt primitive (#1895). */ interface Interrupt { readonly type: 'interrupt'; /** Context shown to the human / written to the checkpoint metadata. */ readonly value: unknown; /** Stable identifier — matched by the resume() call to inject the value. */ readonly id: string; } /** * Re-entry primitive returned by a NodeHandler. Combines state mutation * (`update`) with optional dynamic redirection (`goto`, Phase 2 — not yet * wired) into a single typed envelope. * * In Phase 1 of #1895, only `update` is honored by the executor. `goto` is * accepted in the type to avoid a breaking change when it lands. */ interface Command { readonly type: 'command'; /** State mutations to merge via the standard reducer pipeline. */ readonly update?: Partial; /** Phase 2 — node ID to redirect to. Currently ignored by the executor. */ readonly goto?: string; } /** * Per-execution context passed to NodeHandler. Currently just delivers values * provided to `resumeFromCheckpoint(...)` — the node sees `{interrupt_id: * resumed_value}` on the run that follows the resume call. */ interface NodeContext { /** * Values supplied to the most recent resume() call, keyed by interrupt id. * Empty object when not resuming. Frozen. */ readonly resumeValues: Readonly>; } /** Allowed return shapes for a NodeHandler. */ type NodeReturn = Partial | Interrupt | Command; /** * Handler function for a graph node. Receives current state and an optional * per-run context, returns either: * - `Partial` (legacy, common case) — merged via reducers * - `Command` — `update` portion is merged via reducers * - `Interrupt` — pauses the graph; emits checkpoint with interrupt metadata * * The `ctx` parameter is optional — pre-#1895 handlers that take only `state` * remain valid (additive widening). */ type NodeHandler$1 = (state: Readonly, ctx?: NodeContext) => Promise; /** * A node in the workflow graph. */ interface GraphNode { readonly id: string; readonly handler: NodeHandler$1; readonly timeout?: number | undefined; readonly retries?: number | undefined; /** Precondition hooks run before node execution (Issue #997). */ readonly preconditions?: readonly PreconditionConfig[] | undefined; /** Post-step verification hook run after node execution (Issue #994). */ readonly verify?: NodeHook | undefined; /** * Nodes this node may jump to with `Command.goto` (#5727), mirroring * LangGraph's `ends`. A dynamic jump is an EDGE the static edge set cannot * see, so without declaring it a target reachable only via goto fails * `checkReachability` and the graph will not compile at all. * * Declaring is not the same as scheduling: the handler still decides at run * time whether to jump, and to which of these. The declaration exists so the * builder can validate the topology and so a reader (or a visualizer) can see * the dynamic edge. */ readonly gotoTargets?: readonly string[] | undefined; } /** * Optional per-node settings accepted by `GraphBuilder.addNode`. Mirrors the * optional half of {@link GraphNode}; lives here, beside the node type it * configures, rather than in the builder. */ interface NodeOptions { readonly timeout?: number; readonly retries?: number; readonly preconditions?: readonly PreconditionConfig[]; readonly verify?: NodeHook; /** Nodes this node may reach via `Command.goto` (#5727). */ readonly gotoTargets?: readonly string[]; } /** Special sentinel for the graph entry point. */ declare const START: "__START__"; /** Special sentinel for the graph exit point. */ declare const END: "__END__"; /** * Edge types in the graph. */ type GraphEdge = { readonly type: 'fixed'; readonly from: string; readonly to: string; readonly maxTraversals?: number; } | { readonly type: 'conditional'; readonly from: string; readonly router: (state: Readonly) => string; readonly targets: readonly string[]; readonly maxTraversals?: number; }; /** * Compiled graph definition — validated and ready for execution. * Immutable after compilation. */ interface CompiledGraph { readonly nodes: ReadonlyMap; readonly edges: readonly GraphEdge[]; readonly stateSchema: Readonly; readonly entryEdges: readonly GraphEdge[]; } /** * Result of a single node execution. */ interface NodeResult { readonly nodeId: string; readonly stateUpdates: Partial; readonly durationMs: number; readonly status: 'success' | 'failed' | 'skipped' | 'interrupted'; readonly error?: string; /** * Coarse failure category for a `failed` result (#3534, selective-retry). * Classifies the failure so retry logic can gate on it; only set on failure. */ readonly errorCategory?: ErrorCategory; /** * Whether re-running this failed node is safe (derived from `errorCategory`; * only `transient` is retry-safe by default, #3534). Selective-retry uses * this to re-run transient failures and leave permanent ones alone. */ readonly isRetryable?: boolean; /** * Set when the node failed because a policy gate denied the stage boundary * (#3177). A policy block is terminal and non-retryable: it halts the * pipeline even under `continueOnFailure` (unlike an ordinary failed node, * which continue-mode tolerates). */ readonly policyBlocked?: boolean; /** Set when the node returned an Interrupt envelope (#1895). */ readonly interrupt?: Interrupt; /** * Set when the node returned a Command with `goto`. The executor uses this * to redirect the next runnable set instead of resolving outgoing edges. * Validated against the compiled graph; unknown targets are logged + ignored. * (#2425) */ readonly gotoTarget?: string; } /** * Result of a full graph execution. */ interface GraphExecutionResult { readonly finalState: Readonly; readonly nodeResults: readonly NodeResult[]; readonly totalDurationMs: number; readonly stepsExecuted: number; /** * Set when execution paused on an Interrupt return. The checkpoint * referenced here can be passed to `resumeFromCheckpoint(...)` along with a * matching `{[interruptId]: resumeValue}` map. (#1895) */ readonly halted?: { readonly checkpointId: string; readonly nodeId: string; readonly interruptId: string; readonly value: unknown; }; } /** * Options for graph execution. */ interface GraphExecuteOptions { readonly signal?: AbortSignal; readonly timeout?: number; /** * Maximum node executions. A parallel super-step starts only when its full * batch fits within the remaining budget. */ readonly maxSteps?: number; readonly onNodeComplete?: (result: NodeResult) => void; /** * Prior NodeResults to replay instead of re-executing (#3534, selective-retry). * A node with a `success` entry here is skipped — its result (including * `stateUpdates`) is reused so downstream nodes still see the correct state — * while nodes absent here, or present with a non-`success` status, are * re-executed. Lets `retryFailed` re-run only the failed/skipped nodes while * replaying the prior successes. */ readonly priorResults?: ReadonlyMap; /** Optional checkpoint store for durable execution (Issue #837). */ readonly checkpointStore?: ICheckpointStore; /** Execution ID for checkpoint grouping. Required with checkpointStore. */ readonly executionId?: string; /** Event listener for streaming observation (Issue #838). */ readonly onEvent?: (event: GraphEvent) => void; /** * Values supplied for HITL resume. Keyed by Interrupt id; passed to each * NodeHandler via its NodeContext on this run only. Empty when not * resuming. (#1895) */ readonly resumeValues?: Readonly>; } /** Discriminated union of graph lifecycle events for streaming observation. */ type GraphEvent = { readonly type: 'node_started'; readonly nodeId: string; readonly stepNumber: number; readonly timestamp: number; } | { readonly type: 'node_completed'; readonly nodeId: string; readonly stepNumber: number; readonly durationMs: number; readonly resultKeys: readonly string[]; readonly timestamp: number; } | { readonly type: 'node_error'; readonly nodeId: string; readonly stepNumber: number; readonly error: string; readonly timestamp: number; } | { /** * A node that did not run to completion: it paused for human input * (`interrupted`) or its precondition refused it (`skipped`). * * `NodeResult.status` is four-way, and the emitter's `else` branch used to * fold both of these into `node_completed` — so a node that produced * nothing was published to the hash-chained audit trail as "completed in * 0ms", and a `skipped` result's `error` string was dropped entirely * because the completion event has no slot for it. */ readonly type: 'node_not_completed'; readonly nodeId: string; readonly stepNumber: number; readonly reason: 'interrupted' | 'skipped'; readonly detail?: string; readonly timestamp: number; } | { readonly type: 'state_updated'; readonly stepNumber: number; readonly updatedKeys: readonly string[]; readonly timestamp: number; } | { readonly type: 'step_completed'; readonly stepNumber: number; readonly nodesExecuted: number; readonly timestamp: number; } | { readonly type: 'execution_complete'; readonly totalSteps: number; readonly totalNodes: number; readonly durationMs: number; /** * True when the run stopped awaiting human input rather than finishing. * * `runSuperStepLoop` returns `undefined` on the interrupt path, which is * the same "loop ended normally" signal as running out of runnable nodes, * so this event was emitted unconditionally BEFORE the halt check. A * paused run published a completion indistinguishable from a finished * one, and `halted` — the truthful marker — lives on the returned * `Result`, which an `onEvent` consumer such as the audit bridge never * sees. */ readonly halted?: boolean; readonly timestamp: number; } | { readonly type: 'hook_started'; readonly nodeId: string; readonly hookName: string; readonly hookPhase: 'precondition' | 'verify'; readonly stepNumber: number; readonly timestamp: number; } | { readonly type: 'hook_completed'; readonly nodeId: string; readonly hookName: string; readonly hookPhase: 'precondition' | 'verify'; readonly durationMs: number; readonly stepNumber: number; readonly timestamp: number; } | { readonly type: 'hook_failed'; readonly nodeId: string; readonly hookName: string; readonly hookPhase: 'precondition' | 'verify'; readonly error: string; readonly stepNumber: number; readonly timestamp: number; } | ContextUnavailableEvent; /** * Emitted when unified-memory context retrieval fails at graph start (#3180). * * Best-effort enrichment is preserved — the graph still runs with empty * context — but the failure is now observable instead of swallowed: a * `warn` log plus this event flow through the standard `onEvent`/EventBus * path so a readiness/counter consumer can aggregate context-availability. * * Defined as a single named shape (not inlined) so the three remaining * `getContextForTask` call sites (execute-expert, orchestrate, * composite-router; follow-up #3699) become pure call-site wiring against * one authoritative event contract (DRY). * * `error` carries ONLY a sanitized message (`getErrorMessage`) — never a * stack trace, file-system path, prompt, secret, or token. */ type ContextUnavailableEvent = { readonly type: 'context_unavailable'; /** Inferred task category whose context could not be retrieved. */ readonly category: string; /** Sanitized failure message — message string only, no stack/paths/secrets. */ readonly error: string; /** Correlation id when the execution was given one. */ readonly executionId?: string; readonly timestamp: number; }; /** * Error type for graph compilation failures. */ type GraphCompileError = { type: 'duplicate_node'; nodeId: string; } | { type: 'missing_node'; nodeId: string; referencedBy: string; } | { type: 'cycle_detected'; path: readonly string[]; } | { type: 'no_entry'; message: string; } | { type: 'unreachable_node'; nodeId: string; } | { type: 'missing_reducer'; field: string; }; /** Format a compile error as a human-readable string. */ declare function formatCompileError(error: GraphCompileError): string; /** * Result type for graph compilation. */ type CompileResult$2 = Result; /** * nexus-agents/orchestration - Graph Event Emission * * Helpers for emitting typed graph lifecycle events during execution. * Keeps event logic separate from core executor flow. * * @module orchestration/graph/graph-events * (Source: Issue #838 — EventEmitter streaming) */ /** Minimal context needed for event emission. */ interface StepContext { readonly stepsExecuted: number; readonly runnableIds: readonly string[]; } /** Emits node_started events for all nodes about to execute. */ declare function emitNodeStarted(ctx: StepContext, options?: GraphExecuteOptions): void; /** Emits node_completed or node_error events for each result. */ declare function emitNodeResults(ctx: StepContext, results: readonly NodeResult[], options?: GraphExecuteOptions): void; /** Emits state_updated event with deduplicated keys from successful results. */ declare function emitStateUpdated(ctx: StepContext, results: readonly NodeResult[], options?: GraphExecuteOptions): void; /** Emits step_completed event after a super-step finishes. */ declare function emitStepCompleted(ctx: StepContext, nodesExecuted: number, options?: GraphExecuteOptions): void; /** Emits execution_complete event when graph execution finishes. */ declare function emitExecutionComplete(totalSteps: number, totalNodes: number, durationMs: number, options?: GraphExecuteOptions, halted?: boolean): void; /** * nexus-agents/orchestration - Graph Workflow Builder * * Fluent API for constructing and compiling graph-based workflows. * Validates structure at compile time (before execution): * - All edges reference existing nodes * - No cycles in fixed edges * - All nodes reachable from START * - All state fields have reducers * * @module orchestration/graph/graph-builder * (Source: Issue #831 — Graph-based workflow orchestration) */ declare class GraphBuilder { private readonly nodes; private readonly edges; private readonly stateFields; /** * Registers a state field with its default value and reducer. */ addState(name: string, schema: StateFieldSchema): this; /** * Adds a node to the graph. * Supports optional precondition hooks (Issue #997) and verify hook (Issue #994). */ addNode(id: string, handler: NodeHandler$1, opts?: NodeOptions): this; /** * Adds a fixed edge between two nodes. */ addEdge(from: string, to: string, options?: { maxTraversals?: number; }): this; /** * Adds a conditional edge with a routing function. * The router inspects state and returns the target node ID. * All possible targets must be declared for compile-time validation. */ addConditionalEdge(from: string, router: GraphEdge & { type: 'conditional'; } extends infer E ? E extends { type: 'conditional'; router: infer R; } ? R : never : never, targets: readonly string[]): this; /** * Compiles the graph, validating all structural invariants. * Returns a CompileResult — either a validated CompiledGraph or a compile error. */ compile(): CompileResult$2; private checkDuplicateNodes; private checkEdgeReferences; private checkEntryPoint; private checkCycles; private dfs; private checkReachability; /** * Every declared `gotoTargets` entry must name a real node (#5727). Checked * before reachability so the error names the DECLARING node, rather than * surfacing later as a confusing `unreachable_node` about something else. * * Reports the EXISTING `missing_node` rather than a new error variant: a * declared goto target is an edge reference, so `missing_node`'s own message * ("Edge references non-existent node 'x' (from 'y')") already reads correctly. * Adding a variant would widen a union the library RETURNS, which breaks any * consumer switching exhaustively over `GraphCompileError` — a breaking change * needing a unanimous panel, for a diagnostic distinction nothing consumes. */ private checkGotoTargets; /** * BFS from START over static edges PLUS declared `Command.goto` targets * (#5727). * * Goto targets are followed from the DECLARING node, exactly like an edge — * not seeded from START. That distinction is load-bearing: seeding would make * a target declared on an itself-unreachable node read as reachable, so a * whole orphaned subgraph could bless itself and `unreachable_node` would stop * being able to fail for the graphs that use goto. */ private findReachableNodes; /** Gets initial target nodes from START edges. */ private getStartTargets; /** Gets unvisited targets of outgoing edges from a node. */ private getEdgeTargets; } /** Creates an overwrite reducer (last write wins). */ declare function overwrite(defaultValue: T): StateFieldSchema; /** Creates an append reducer for array fields. */ declare function append(defaultValue?: T[]): StateFieldSchema; /** Creates a custom reducer with a merge function. */ declare function customReducer(defaultValue: T, merge: StateReducer & { type: 'custom'; } extends infer R ? R extends { merge: infer M; } ? M : never : never): StateFieldSchema; /** * nexus-agents/orchestration - Graph Workflow Executor * * Executes compiled graph workflows using super-step (BSP) model: * 1. Find all nodes with satisfied dependencies (in-degree 0) * 2. Execute them in parallel * 3. Merge state updates using reducers * 4. Repeat until END is reached or max steps exhausted * * @module orchestration/graph/graph-executor * (Source: Issue #831 — Graph-based workflow orchestration) */ /** * Executes a compiled graph workflow. * * Uses a super-step model: each step finds all runnable nodes, * executes them in parallel, merges state, then resolves edges * to find the next set of runnable nodes. */ declare function executeGraph(graph: CompiledGraph, initialInputs: Readonly, options?: GraphExecuteOptions): Promise>; /** * nexus-agents/orchestration - Graph Workflow Hooks * * Execution logic for precondition and post-step verification hooks. * Keeps hook concerns separate from the core executor flow. * * @module orchestration/graph/graph-hooks * (Source: Issue #994 — Post-step verification, Issue #997 — Pre-condition hooks) */ /** Result of running all preconditions for a node. */ interface PreconditionResult { readonly passed: boolean; readonly results: readonly PreconditionOutcome[]; } /** Outcome of a single precondition hook. */ interface PreconditionOutcome { readonly name: string; readonly passed: boolean; readonly durationMs: number; readonly error?: string | undefined; } /** Result of running verification on a node. */ interface VerificationResult { readonly passed: boolean; readonly durationMs: number; readonly error?: string | undefined; } /** * Runs all precondition hooks for a node. * If any required precondition fails, returns passed=false. * Optional precondition failures are logged but don't block execution. */ declare function runPreconditions(node: GraphNode, state: Readonly, stepNumber: number, options?: GraphExecuteOptions): Promise; /** * Runs the post-step verification hook for a node. * Returns the verification result. */ declare function runVerification(node: GraphNode, state: Readonly, stepNumber: number, options?: GraphExecuteOptions): Promise; /** * Creates a state-comparison verification hook. * Checks that specified state fields changed after node execution. */ declare function createStateComparisonVerifier(fields: readonly string[]): (preState: Readonly) => PreconditionConfig['hook']; /** * Creates a precondition that checks state field values. * Useful for enforcing invariants before node execution. */ declare function createStateGuard(name: string, predicate: (state: Readonly) => boolean, errorMessage: string): PreconditionConfig; /** * nexus-agents/orchestration - In-Memory Checkpoint Store * * Default checkpoint store using bounded in-memory storage. * Suitable for development and testing. For production durability, * implement ICheckpointStore with a persistent backend. * * @module orchestration/graph/checkpoint-store * (Source: Issue #833 — Orchestrator checkpointing) */ /** * In-memory checkpoint store with bounded storage. * Checkpoints are evicted on a per-execution basis (oldest first) * when limits are exceeded. */ declare class InMemoryCheckpointStore implements ICheckpointStore { private readonly checkpoints; private readonly byExecution; save(checkpoint: Checkpoint): void; load(id: string): Checkpoint | undefined; latest(executionId: string): Checkpoint | undefined; list(executionId: string): readonly CheckpointSummary[]; delete(id: string): boolean; deleteExecution(executionId: string): number; size(): number; clear(): void; private enforcePerExecutionLimit; private enforceGlobalLimit; } /** * Creates a checkpoint from the current execution state. */ declare function createCheckpoint(opts: { executionId: string; stepNumber: number; state: Readonly; pendingNodeIds: readonly string[]; completedResults: readonly NodeResult[]; metadata?: Record; /** Set when persisting an interrupt-flavored checkpoint (#1895). */ interrupt?: CheckpointInterrupt; }): Checkpoint; /** * Creates a new InMemoryCheckpointStore. */ declare function createCheckpointStore(): ICheckpointStore; /** * Consensus gate node (#3267) — an in-graph consensus checkpoint. * * Generalizes the proven dev-pipeline `vote` stage pattern * (`createVoteStageWrapper`) into a reusable, layer-agnostic primitive: run an * injected voter on a proposal, produce a typed verdict, and let the caller * branch on it (approve → continue, reject → halt/revise) via the graph's * conditional edges. The voter is injected (callback), so the node is decoupled * from any specific voter panel — a 7/3-role consensus panel, a single model, or * the dev-pipeline's `stages.vote` can all satisfy {@link ConsensusVoter}. * * Both the graph adapter ({@link createConsensusGateNode}) and the pipeline * `vote` stage delegate to {@link runConsensusGate}, so there is ONE * consensus-gate implementation (anti-sprawl — #3267 vote condition), not two. * * @module orchestration/graph/consensus-node * (Source: #3267) */ /** What a consensus voter is asked to evaluate. */ interface ConsensusProposalInput { /** The proposal text under review (e.g. a plan). */ readonly proposal: string; /** Optional supporting context (e.g. research) the voter may weigh. */ readonly context?: string; } /** The typed verdict a consensus round produces. */ interface ConsensusVerdict { /** * Whether the proposal cleared the consensus bar. * * `no_quorum` (#4135) is DISTINCT from `rejected`: the panel could not reach a * valid quorum (an errored/absent voice under the opt-in `absolute_quorum` * policy, or an error-policy short-circuit) — a recoverable "re-run the missing * voice" state, NOT the panel rejecting the proposal. A voter that maps a * `consensus_vote` result into a verdict should surface the vote's `decision` * here so `no_quorum` propagates. It is not `success` — pair the gate with a * conditional edge that routes `no_quorum` to a bounded re-vote/escalate rather * than the reject/revise path. The voter-throw fail-closed path stays `rejected` * (an exception is an error, not a valid quorum void). Inert until a caller opts * into `absolute_quorum`. */ readonly outcome: 'approved' | 'rejected' | 'no_quorum'; /** Reviewer feedback (empty on a clean approval). */ readonly feedback: string; /** Optional structured detail (approval %, the raw vote, …) for consumers. */ readonly detail?: Record; } /** Injected voter: run a consensus round and return a verdict. */ type ConsensusVoter = (input: ConsensusProposalInput) => Promise; /** * Run the consensus gate (the single shared implementation). On any voter * error/timeout this **fails CLOSED** to a `rejected` verdict — a gate must * never let unreviewed work through on an error. The voter receives only the * proposal/context (no secrets, no ambient state). */ declare function runConsensusGate(voter: ConsensusVoter, input: ConsensusProposalInput): Promise; /** Options for {@link createConsensusGateNode}. */ interface ConsensusGateNodeOptions { /** The voter to run at this gate. */ readonly voter: ConsensusVoter; /** Graph-state key the typed verdict is written under. */ readonly verdictKey: string; /** Derive the proposal/context from graph state (no secrets/ambient state). */ readonly proposalFrom: (state: Readonly) => ConsensusProposalInput; } /** * Build a {@link NodeHandler} that runs a consensus gate and writes the typed * verdict to `verdictKey` in graph state. Pair it with `addConditionalEdge` on * `state[verdictKey].outcome` to route approve → continue, reject → halt/revise. */ declare function createConsensusGateNode(options: ConsensusGateNodeOptions): NodeHandler$1; /** Options for {@link runGraphWithConsensus}. */ interface RunGraphWithConsensusOptions { /** * Work node that produces the proposal — it must write the proposal text to * `proposalKey` (default `'proposal'`) in its returned state patch. */ readonly produce: NodeHandler$1; /** The voter run at the gate. */ readonly voter: ConsensusVoter; /** State key the produce node writes the proposal to. Default `'proposal'`. */ readonly proposalKey?: string; /** State key the verdict is written to. Default `'consensusVerdict'`. */ readonly verdictKey?: string; /** Initial graph state. */ readonly initialState?: GraphState; } /** * Convenience composition (#3267): run a single work node, then a consensus * gate over its output — `START → produce → consensus → END` — and return the * execution result plus the typed verdict. The `proposalKey`/`verdictKey` state * channels are declared automatically. For richer control flow (branch on the * verdict, loop on reject, multiple gates) use {@link createConsensusGateNode} * with {@link GraphBuilder} + `addConditionalEdge` directly. */ declare function runGraphWithConsensus(options: RunGraphWithConsensusOptions): Promise>; /** * nexus-agents/mcp - Predefined Graph Workflow Templates * * Registry of graph workflow factories for the run_graph_workflow tool. * Each factory builds a CompiledGraph using the GraphBuilder API. * * Available workflows: * - echo: Simple input echo (demo) * - pipeline: Two-step validate-process pipeline (demo) * - code-review: Complexity-based code review with conditional routing * - security-scan: Multi-step security analysis with severity routing * * @module mcp/tools/run-graph-workflow-templates * (Source: Issue #841 — Real-world graph workflow templates) */ type GraphFactory = () => CompiledGraph | undefined; interface GraphWorkflowInfo { readonly name: string; readonly description: string; readonly inputFields: readonly string[]; readonly nodeCount: number; readonly hasConditionalEdges: boolean; } /** Returns metadata about all available graph workflows (built-in + multi-CLI + security setup). */ declare function getGraphWorkflowList(): readonly GraphWorkflowInfo[]; /** Registry of all predefined graph workflows (built-in + multi-CLI + security setup). */ declare function getGraphRegistry(): ReadonlyMap; /** * nexus-agents/mcp - List Experts Tool * * MCP tool for discovering available expert types. * Provides discoverability for the create_expert tool. * * @module mcp/tools/list-experts * (Source: Issue #436 - Add discoverability tools) * (Refactored: Issue #531 - Use createSecureHandlerFactory) */ /** * Input schema for list_experts tool. * Currently no parameters required (lists all experts). */ declare const ListExpertsInputSchema: z.ZodObject<{ format: z.ZodDefault>>; }, z.core.$strip>; /** * Type for validated list experts input. */ type ListExpertsInput = z.infer; /** * Dependencies for list_experts tool. */ type ListExpertsDeps = BaseMcpToolDeps; /** * Expert information returned by list_experts tool. */ interface ExpertInfo { /** Role identifier for create_expert */ role: string; /** Human-readable name */ name: string; /** Expert description */ description: string; /** List of capabilities */ capabilities: readonly string[]; } /** * Response from list_experts tool. */ interface ListExpertsResponse { /** List of available experts */ experts: ExpertInfo[]; /** Total count */ count: number; } /** * Registers the list_experts tool with the MCP server. * * Uses createSecureHandler for standardized security middleware (Issue #531). * Includes timeout protection for CVE-2026-0621 mitigation (Issue #271). * * @category MCP * @param server - MCP server instance * @param deps - Tool dependencies */ declare function registerListExpertsTool(server: McpServer, deps: ListExpertsDeps): void; /** * nexus-agents/mcp - List Workflows Tool * * MCP tool for discovering available workflow templates. * Provides discoverability for the run_workflow tool. * * @module mcp/tools/list-workflows * (Source: Issue #436 - Add discoverability tools) * (Refactored: Issue #531 - Use createSecureHandlerFactory) */ /** * Input schema for list_workflows tool. */ declare const ListWorkflowsInputSchema: z.ZodObject<{ category: z.ZodOptional; format: z.ZodDefault>>; }, z.core.$strip>; /** * Type for validated list workflows input. */ type ListWorkflowsInput = z.infer; /** * Dependencies for list_workflows tool. */ interface ListWorkflowsDeps extends BaseMcpToolDeps { /** Workflow engine for listing templates */ workflowEngine: IWorkflowEngine; } /** * Workflow information returned by list_workflows tool. */ interface WorkflowInfo { /** Template name for run_workflow */ name: string; /** Version string */ version: string; /** Workflow description */ description: string | undefined; /** Workflow category */ category: string | undefined; } /** * Response from list_workflows tool. */ interface ListWorkflowsResponse { /** List of available workflows */ workflows: WorkflowInfo[]; /** Total count */ count: number; /** Categories found (for filtering hints) */ categories?: string[]; } /** * Registers the list_workflows tool with the MCP server. * * Uses createSecureHandler for standardized security middleware (Issue #531). * Includes timeout protection for CVE-2026-0621 mitigation (Issue #271). * * @category MCP * @param server - MCP server instance * @param deps - Tool dependencies */ declare function registerListWorkflowsTool(server: McpServer, deps: ListWorkflowsDeps): void; /** * nexus-agents/mcp - Execute Expert Tool * * MCP tool for executing tasks with previously created expert agents. * Experts must be created first using the create_expert tool. * * @module mcp/tools/execute-expert * (Source: Issue #437 - Add execute_expert tool) * (Refactored: Issue #1298 - MCP Tasks async execution; its task handler * lives in `execute-expert-task-handler.ts` since #6148) */ /** * Input schema for execute_expert tool. */ declare const ExecuteExpertInputSchema: z.ZodObject<{ expertId: z.ZodString; task: z.ZodString; context: z.ZodOptional>; timeoutMs: z.ZodOptional; previousExpertSummary: z.ZodOptional; }, z.core.$strip>; /** * Type for validated execute expert input. */ type ExecuteExpertInput = z.infer; /** * Dependencies for execute_expert tool. */ interface ExecuteExpertDeps extends BaseMcpToolDeps { /** Registry of created experts (shared with create_expert) */ expertRegistry: Map; /** * Durable, hash-chained audit logger (#4097). Its only reader was the * access-constraint deriver's ALS audit trail, deleted in #5108; nothing in * this tool consumes it today. Kept because `ExecuteExpertDeps` is published * — dropping the member is a breaking change for the next major (#6319). */ auditLogger?: IAuditLogger; /** Optional CLI detection cache for checking available CLIs (Issue #747) */ cliCache?: ICliDetectionCache; /** MCP notifier for client-visible logging (Issue #974) */ notifier?: IMcpNotifier | undefined; } /** * Response from execute_expert tool. */ interface ExecuteExpertResponse { /** Expert ID that executed the task */ expertId: string; /** Expert role */ role: string; /** Task execution output */ output: string; /** Execution duration in milliseconds */ durationMs: number; /** Token usage from the model */ tokensUsed: number; /** * Whether `tokensUsed` is measured. `false` means the adapter reported no * usage, so `tokensUsed` is a placeholder zero rather than a measurement. */ tokensMeasured?: boolean; /** Status of execution */ status: 'success' | 'error'; /** Error message if status is 'error' */ error?: string; /** Model used for execution (Issue #817) */ modelUsed?: string; /** * The expert's self-reported confidence in `[0, 1]` (#3766). Present only when * the expert emitted an {@link ExpertOutput}-shaped analysis carrying a numeric * confidence; absent for plain-string outputs. Consumers can route/weight on it. */ confidence?: number; } /** * Registers the execute_expert tool with the MCP server. * * Uses MCP Tasks primitive (SEP-1686) via registerToolTask for async execution. * taskSupport: 'optional' preserves sync fallback for clients without task support. * * NOT wrapped by createSecureHandler or wrapToolWithTimeout (#4981). Of the 46 * tool modules this is the only one outside the standard middleware stack: it * registers through registerToolTask, so it creates no RequestContext, emits * no `Tool invocation started` pair, and no tool-audit record. An earlier * version of this comment claimed it used createSecureHandler (Issue #531) * and that it carried the #271 timeout protection; neither is true as wired. * Whether the tasks primitive can take those wrappers is part of #4978. * * @category MCP * @param server - MCP server instance * @param deps - Tool dependencies */ declare function registerExecuteExpertTool(server: McpServer, deps: ExecuteExpertDeps): void; interface ConsensusVoteDeps extends BaseMcpToolDeps { /** MCP notifier for client-visible logging (Issue #974) */ notifier?: IMcpNotifier | undefined; /** * In-process gateway model adapters (#4040). When the server has a configured * OpenAI-compatible gateway, voters route through these HTTP adapters instead * of shelling out to a CLI subprocess — no per-subprocess key forwarding, and * the nested-spawn deadlock (#4033) cannot occur. Omitted ⇒ CLI voter path. */ gatewayAdapters?: readonly IModelAdapter[] | undefined; } /** * Registers the consensus_vote tool with the MCP server. * Uses createSecureHandler (Issue #531) with timeout protection (Issue #271). * @category MCP */ declare function registerConsensusVoteTool(server: McpServer, deps: ConsensusVoteDeps): void; /** * nexus-agents/mcp - Research Query Tool * * MCP tool for querying the research registry. * Wraps existing CLI helpers: getResearchStatus(), findOverlaps(), generateStatsJson(). * * @module mcp/tools/research-query * (Source: Research System Enhancement - Phase 1A) */ /** * Input schema for research_query tool. */ declare const ResearchQueryInputSchema: z.ZodObject<{ action: z.ZodEnum<{ status: "status"; search: "search"; stats: "stats"; overlap: "overlap"; }>; techniqueId: z.ZodOptional; query: z.ZodOptional; status: z.ZodDefault>>; threshold: z.ZodDefault>; }, z.core.$strip>; /** * Type for validated research query input. */ type ResearchQueryInput = z.infer; /** * Dependencies for research_query tool. */ type ResearchQueryDeps = BaseMcpToolDeps; /** * Response from research_query tool. */ interface ResearchQueryResponse { /** Action that was performed */ action: string; /** Whether the query succeeded */ success: boolean; /** Query results */ data: unknown; /** * A recorded rejection for the queried technique, when one exists (#4555). * * Advisory. The registry says a prior attempt failed and why; it does not * suppress the result, because a prior rejection is evidence to weigh, not * a veto. */ rejectionNotice?: string; /** Present when the negative-results registry could not be measured. */ negativeResults?: { status: 'unavailable'; reason: string; }; } /** * Registers the research_query tool with the MCP server. * * @category MCP * @param server - MCP server instance * @param deps - Tool dependencies */ declare function registerResearchQueryTool(server: McpServer, deps: ResearchQueryDeps): void; /** * nexus-agents/mcp - Research Add Tool * * MCP tool for adding papers to the research registry. * Wraps existing CLI helpers: addResearchPaper(), fetchArxivMetadataResult(). * * @module mcp/tools/research-add * (Source: Research System Enhancement - Phase 1B) */ /** * Input schema for research_add tool. */ declare const ResearchAddInputSchema: z.ZodObject<{ arxivId: z.ZodString; topic: z.ZodOptional; priority: z.ZodOptional>; dryRun: z.ZodDefault>; }, z.core.$strip>; /** * Type for validated research add input. */ type ResearchAddInput = z.infer; /** * Dependencies for research_add tool. */ type ResearchAddDeps = BaseMcpToolDeps; /** * Response from research_add tool. */ interface ResearchAddResponse { /** Whether the operation succeeded */ success: boolean; /** Paper ID */ paperId: string; /** Paper title (empty on failure) */ title: string; /** Human-readable message */ message: string; /** Whether this was a dry run */ dryRun: boolean; /** * Error category when `success` is false (#2649). `business` for a * dedup hit (paper already in registry); absent otherwise — the MCP * handler treats absent as `internal`. */ errorCategory?: ErrorCategory; } /** * Registers the research_add tool with the MCP server. * * @category MCP * @param server - MCP server instance * @param deps - Tool dependencies */ declare function registerResearchAddTool(server: McpServer, deps: ResearchAddDeps): void; /** * nexus-agents/mcp - Research Add Source Tool * * MCP tool for adding non-paper sources (repos, tools, blogs) to the * research registry. The quality_score is computed from the quality_signals * the caller provides — no GitHub metadata is fetched (provide signals * explicitly). * * @module mcp/tools/research-add-source * @see Issue #1580 */ declare const ResearchAddSourceInputSchema: z.ZodObject<{ url: z.ZodString; name: z.ZodString; type: z.ZodEnum<{ specification: "specification"; code_analysis: "code_analysis"; product_docs: "product_docs"; research_blog: "research_blog"; open_source_repo: "open_source_repo"; }>; vendor: z.ZodOptional; topics: z.ZodOptional>; tags: z.ZodOptional>; quality_signals: z.ZodOptional; language: z.ZodOptional; has_tests: z.ZodOptional; has_docs: z.ZodOptional; has_paper: z.ZodOptional; }, z.core.$strip>>; techniques_extracted: z.ZodOptional>; verdict: z.ZodOptional>; verdict_notes: z.ZodOptional; dryRun: z.ZodDefault>; }, z.core.$strip>; type ResearchAddSourceInput = z.infer; type ResearchAddSourceDeps = BaseMcpToolDeps; interface ResearchAddSourceResponse { success: boolean; sourceId: string; name: string; quality_score: number; evidence_tier: string; message: string; dryRun: boolean; /** * Error category when `success` is false (#2649). `business` for a * dedup hit (source already in registry), `internal` for a write * failure; absent otherwise. */ errorCategory?: ErrorCategory; } /** @category MCP */ declare function registerResearchAddSourceTool(server: McpServer, deps: ResearchAddSourceDeps): void; /** * nexus-agents/mcp - Research Analyze Tool * * MCP tool for analyzing the research registry for gaps, trends, * priorities, stale entries, and coverage. * * @module mcp/tools/research-analyze * (Source: Research System Enhancement - Phase 1D) */ /** * Input schema for research_analyze tool. */ declare const ResearchAnalyzeInputSchema: z.ZodObject<{ focus: z.ZodEnum<{ trends: "trends"; coverage: "coverage"; gaps: "gaps"; priorities: "priorities"; stale: "stale"; }>; topic: z.ZodOptional; }, z.core.$strip>; /** * Type for validated research analyze input. */ type ResearchAnalyzeInput = z.infer; /** * Dependencies for research_analyze tool. */ type ResearchAnalyzeDeps = BaseMcpToolDeps; /** * Response from research_analyze tool. */ interface ResearchAnalyzeResponse { /** Analysis focus that was performed */ focus: string; /** Whether the analysis succeeded */ success: boolean; /** Analysis results */ analysis: unknown; /** Recommendations based on analysis */ recommendations: string[]; } /** * Registers the research_analyze tool with the MCP server. * * @category MCP * @param server - MCP server instance * @param deps - Tool dependencies */ declare function registerResearchAnalyzeTool(server: McpServer, deps: ResearchAnalyzeDeps): void; /** * nexus-agents/mcp - Research Catalog Review Tool * * MCP tool for reviewing auto-cataloged research references. * Actions: list, approve, dismiss, flush. * * @module mcp/tools/research-catalog-review * (Source: Research System Enhancement - Phase 5) */ /** * Input schema for research_catalog_review tool. */ declare const ResearchCatalogReviewInputSchema: z.ZodObject<{ action: z.ZodEnum<{ list: "list"; approve: "approve"; dismiss: "dismiss"; flush: "flush"; }>; identifier: z.ZodOptional; topic: z.ZodOptional; createIssue: z.ZodDefault>; }, z.core.$strip>; /** * Dependencies for research_catalog_review tool. */ type ResearchCatalogReviewDeps = BaseMcpToolDeps; /** * Registers the research_catalog_review tool with the MCP server. * * @category MCP * @param server - MCP server instance * @param deps - Tool dependencies */ declare function registerResearchCatalogReviewTool(server: McpServer, deps: ResearchCatalogReviewDeps): void; /** * nexus-agents/mcp - Research Synthesize Tool * * MCP tool for synthesizing the research registry by grouping papers * into topic clusters and generating structured synthesis summaries * with themes, findings, techniques, and implementation opportunities. * * @module mcp/tools/research-synthesize * (Source: Issue #1386 — Research Synthesis Pipeline) */ /** * Input schema for research_synthesize tool. */ declare const ResearchSynthesizeInputSchema: z.ZodObject<{ topic: z.ZodOptional; }, z.core.$strip>; /** * Type for validated research synthesize input. */ type ResearchSynthesizeInput = z.infer; type ResearchSynthesizeDeps = BaseMcpToolDeps; /** * Registers the research_synthesize tool with the MCP server. * * @category MCP * @param server - MCP server instance * @param deps - Tool dependencies */ declare function registerResearchSynthesizeTool(server: McpServer, deps: ResearchSynthesizeDeps): void; /** * nexus-agents/mcp - Issue Triage Tool * * MCP tool for automated GitHub issue triage using the full * security pipeline (8/8 modules). Read-only by default. * * @module mcp/tools/issue-triage-tool * (Source: Issue #828 — Wire remaining security modules) */ declare const IssueTriageInputSchema: z.ZodObject<{ issueUrl: z.ZodString; dryRun: z.ZodDefault>; }, z.core.$strip>; type IssueTriageInput = z.infer; type IssueTriageDeps = BaseMcpToolDeps; interface IssueTriageResponse { readonly issueNumber: number; readonly repository: string; readonly category: string; readonly categoryConfidence: number; readonly trustAssessment: { readonly trustTier: string; readonly userRole: string; readonly reputationScore?: number | undefined; readonly isSuspicious: boolean; readonly suspiciousSignals: readonly string[]; }; readonly proposedActions: ReadonlyArray<{ readonly type: string; readonly description: string; readonly policyApproved: boolean; readonly corroborated: boolean; /** Present when refused: the rules the policy gate (or a corroboration refusal) recorded (#6309). */ readonly policyViolations?: readonly string[]; /** Present when refused or uncorroborated: the unmet corroboration requirements. */ readonly missingCorroboration?: readonly string[]; /** Present when the firewall refused the action at its corroboration stage under `enforce`. */ readonly refusedAtStage?: 'corroboration'; }>; readonly durationMs: number; } /** * Registers the issue_triage tool with the MCP server. * Uses createSecureHandler for rate limiting and input sanitization. * @category MCP */ declare function registerIssueTriageTool(server: McpServer, deps: IssueTriageDeps): void; declare const RunGraphWorkflowInputSchema: z.ZodObject<{ dispatch: z.ZodDefault; mode: RejectedModeKey; workflow: z.ZodString; inputs: z.ZodDefault>>; enableCheckpointing: z.ZodDefault>; enableAuditTrail: z.ZodDefault>; }, z.core.$strip>; type RunGraphWorkflowInput = z.infer; interface RunGraphWorkflowDeps extends BaseMcpToolDeps { /** MCP notifier for client-visible logging (Issue #974) */ readonly notifier?: IMcpNotifier | undefined; /** * Durable audit logger (#5219). Without it, `enableAuditTrail` produced a * trail that was never persisted: `graph_execution` records sat in an * in-memory array capped at 10,000, evicted oldest-first, and gone on exit — * never reaching the hash chain `verify_audit_chain` reads. * * Threaded the same way `execute_expert` and `orchestrate` receive theirs. */ readonly auditLogger?: IAuditLogger | undefined; } interface RunGraphWorkflowResponse { readonly workflow: string; readonly status: 'completed' | 'failed'; readonly finalState: Readonly; readonly stepsExecuted: number; readonly nodesExecuted: number; readonly durationMs: number; readonly events: readonly GraphEventSummary[]; readonly checkpointCount: number; readonly error?: string | undefined; } interface GraphEventSummary { readonly type: string; readonly nodeId?: string | undefined; readonly detail?: string | undefined; } /** Registers the run_graph_workflow tool with an MCP server. @category MCP */ declare function registerRunGraphWorkflowTool(server: McpServer, deps: RunGraphWorkflowDeps): void; declare const ExecuteSpecInputSchema: z.ZodObject<{ dispatch: z.ZodDefault; mode: RejectedModeKey; spec: z.ZodString; dryRun: z.ZodDefault>; }, z.core.$strip>; type ExecuteSpecInput = z.infer; type ExecuteSpecDeps = BaseMcpToolDeps; /** Registers the execute_spec tool with an MCP server. @category MCP */ declare function registerExecuteSpecTool(server: McpServer, deps: ExecuteSpecDeps): void; /** * Tool Memory Types * * Shared types for the tool-memory module, extracted to avoid * circular imports between tool-memory.ts and tool-memory-query.ts. * * @module mcp/tools/tool-memory-types */ /** * Result from unified cross-memory query (Phase 3 #746). * Includes source attribution and relevance scoring. */ interface UnifiedMemoryResult { /** Source memory system */ source: 'session' | 'belief' | 'agentic' | 'typed' | 'adaptive'; /** Type of memory entry */ type: string; /** Content summary (may be truncated) */ content: string; /** Relevance score (0-1) based on keyword matching */ relevance: number; /** When the entry was created, or the query time when creation time is unavailable */ timestamp: Date; /** * 'recorded' when the backend persisted a creation time; 'query-time' when the entry * predates creation-time tracking and `timestamp` is only the time of this query (not * when the entry was created). Absent on backends that always had real timestamps. */ readonly timestampSource?: 'recorded' | 'query-time'; /** Additional metadata (e.g., confidence, keywords) */ metadata?: Record; } /** * nexus-agents/mcp - Memory Query Tool * * MCP tool for unified memory search across all backends. * Exposes ToolMemoryManager.queryAll() as an MCP tool. * * @module mcp/tools/memory-query * (Source: Issue #751 - Memory observability MCP tools) */ /** * Input schema for memory_query tool. */ declare const MemoryQueryInputSchema: z.ZodObject<{ query: z.ZodString; limit: z.ZodDefault>; source: z.ZodDefault>>; }, z.core.$strip>; /** * Type for validated memory query input. */ type MemoryQueryInput = z.infer; /** * Dependencies for memory_query tool. */ type MemoryQueryDeps = BaseMcpToolDeps; /** * Response from memory_query tool. */ interface MemoryQueryResponse { /** Query that was executed */ query: string; /** LLM-expanded query when reflective memory rewrites it (Issue #1397 Gap 1). */ expandedQuery?: string; /** Results from memory search */ results: readonly UnifiedMemoryResult[]; /** Total results returned */ count: number; /** Source filter applied */ source: string; /** * Which backends the search could actually reach (#4999). * * `count: 0` used to be the same observation whether nothing matched or the * SQLite-backed stores were absent — every unavailable backend contributes * `[]` silently. A caller asking "do we know anything about X?" was told * "no" when the honest answer was "two of the four stores were not there". */ searched: readonly string[]; /** Backends skipped because they are not configured on this install. */ unavailable: readonly string[]; /** * Backends that were installed and threw while answering (#4999). * * Distinct from `unavailable`: the store is here, it just could not answer. * Each helper swallows its own failure into an empty result set, so without * this a corrupted SQLite file read exactly like a store with no matches. */ errored: readonly string[]; } /** * Registers the memory_query tool with the MCP server. * * @category MCP * @param server - MCP server instance * @param deps - Tool dependencies */ declare function registerMemoryQueryTool(server: McpServer, deps: MemoryQueryDeps): void; /** * nexus-agents/mcp - Memory Stats Tool * * MCP tool for memory system observability dashboard. * Aggregates stats from all memory backends. * * @module mcp/tools/memory-stats * (Source: Issue #751 - Memory observability MCP tools) */ /** * Input schema for memory_stats tool. */ declare const MemoryStatsInputSchema: z.ZodObject<{ includeDecay: z.ZodDefault>; }, z.core.$strip>; /** * Dependencies for memory_stats tool. */ type MemoryStatsDeps = BaseMcpToolDeps; /** * Session memory statistics. */ interface SessionStats { learningsCount: number; tasksCount: number; errorsCount: number; } /** * Belief memory statistics. */ interface BeliefStats { beliefsCount: number; available: boolean; } /** * Backend availability status. */ interface BackendStatus { session: boolean; belief: boolean; agentic: boolean; adaptive: boolean; typed: boolean; mobimem: boolean; decay: boolean; } /** * Per-domain row from the unified MemoryRegistry (Phase 5 of #2766). * Surfaces every backend that registered itself with `getMemoryRegistry()` * so future consumers can iterate one canonical source instead of the * hand-maintained per-backend fields above. */ interface RegistryDomainStats { /** Domain name (e.g., 'belief', 'agentic', 'outcomes'). */ domain: string; /** Row count, or null if the backend's stats() rejected. */ count: number | null; /** Error message when the backend's stats() rejected. */ error: string | null; } /** * Response from memory_stats tool. */ interface MemoryStatsResponse { /** Backend availability status */ backends: BackendStatus; /** Session memory stats */ session: SessionStats; /** Belief memory stats */ belief: BeliefStats; /** Typed memory stats (if available) */ typed: Record | null; /** MobiMem stats (if available) */ mobimem: Record | null; /** Decay stats (if available and requested) */ decay: Record | null; /** * Per-domain stats from the unified MemoryRegistry (Phase 5 of #2766). * One entry per attached backend; empty when no backend has registered. */ registry: readonly RegistryDomainStats[]; /** Timestamp of stats collection */ collectedAt: string; } /** * Registers the memory_stats tool with the MCP server. * * @category MCP * @param server - MCP server instance * @param deps - Tool dependencies */ declare function registerMemoryStatsTool(server: McpServer, deps: MemoryStatsDeps): void; /** * nexus-agents/mcp - Memory Write Tool * * MCP tool for manual memory injection across backends. * Supports session (learnings), belief (triples), agentic (knowledge), * adaptive (priority-scored), and typed (MIRIX-style) writes. * * @module mcp/tools/memory-write * (Source: Issue #1090 - Add memory_write MCP tool) */ /** * Input schema for memory_write tool. */ declare const MemoryWriteInputSchema: z.ZodObject<{ key: z.ZodString; content: z.ZodString; backend: z.ZodEnum<{ session: "session"; belief: "belief"; agentic: "agentic"; adaptive: "adaptive"; typed: "typed"; }>; confidence: z.ZodDefault>>; metadata: z.ZodOptional>; }, z.core.$strip>; /** * Type for validated memory write input. */ type MemoryWriteInput = z.infer; /** * Dependencies for memory_write tool. */ type MemoryWriteDeps = BaseMcpToolDeps; /** * Response from memory_write tool. */ interface MemoryWriteResponse { /** Whether the write succeeded */ success: boolean; /** Target backend */ backend: string; /** Key/subject written */ key: string; /** Whether write was skipped due to identical content already existing (#1455) */ deduplicated?: boolean; /** Error message if write failed */ error?: string; } /** * Registers the memory_write tool with the MCP server. * * @category MCP * @param server - MCP server instance * @param deps - Tool dependencies */ declare function registerMemoryWriteTool(server: McpServer, deps: MemoryWriteDeps): void; /** * nexus-agents/benchmarks - Type Definitions * * Types for performance benchmarking and metrics collection. * * @module benchmarks/benchmark-types * (Source: Issue #156, Mem0 metrics validation) */ /** * Latency percentile metrics. */ interface LatencyMetrics { /** Minimum latency in milliseconds. */ readonly min: number; /** Maximum latency in milliseconds. */ readonly max: number; /** Mean latency in milliseconds. */ readonly mean: number; /** 50th percentile (median) in milliseconds. */ readonly p50: number; /** 75th percentile in milliseconds. */ readonly p75: number; /** 90th percentile in milliseconds. */ readonly p90: number; /** 95th percentile in milliseconds. */ readonly p95: number; /** 99th percentile in milliseconds. */ readonly p99: number; /** Standard deviation in milliseconds. */ readonly stdDev: number; /** Total number of samples. */ readonly sampleCount: number; } /** * Throughput metrics. */ interface ThroughputMetrics { /** Operations per second. */ readonly opsPerSecond: number; /** Total operations completed. */ readonly totalOps: number; /** Total duration in milliseconds. */ readonly durationMs: number; } /** * Token usage metrics. */ interface TokenMetrics { /** Total input tokens. */ readonly inputTokens: number; /** Total output tokens. */ readonly outputTokens: number; /** Total tokens (input + output). */ readonly totalTokens: number; /** Average tokens per operation. */ readonly avgTokensPerOp: number; } /** * Quality metrics for retrieval operations. */ interface QualityMetrics { /** Precision: relevant retrieved / total retrieved. */ readonly precision: number; /** Recall: relevant retrieved / total relevant. */ readonly recall: number; /** F1 score: harmonic mean of precision and recall. */ readonly f1Score: number; /** Mean reciprocal rank. */ readonly mrr: number; /** Normalized discounted cumulative gain at k. */ readonly ndcgAtK: number; /** * Queries whose search call returned an error (#5689). Each is scored as * zero precision/recall/MRR rather than dropped from the average. */ readonly failedQueries?: number; } /** * Resource usage metrics. */ interface ResourceMetrics { /** Peak memory usage in bytes. */ readonly peakMemoryBytes: number; /** Average memory usage in bytes. */ readonly avgMemoryBytes: number; /** CPU time in milliseconds. */ readonly cpuTimeMs: number; /** Database file size in bytes (if applicable). */ readonly dbSizeBytes?: number; } /** * Benchmark result for a single operation type. */ interface OperationBenchmark { /** Operation name. */ readonly operation: string; /** Dataset size used. */ readonly datasetSize: number; /** Latency metrics. */ readonly latency: LatencyMetrics; /** Throughput metrics. */ readonly throughput: ThroughputMetrics; /** Resource metrics. */ readonly resources: ResourceMetrics; /** Quality metrics (for retrieval operations). */ readonly quality?: QualityMetrics; /** Timestamp when benchmark was run. */ readonly timestamp: string; } /** * Complete benchmark suite result. */ interface BenchmarkSuiteResult { /** Suite name. */ readonly name: string; /** Component being benchmarked. */ readonly component: string; /** Version of the component. */ readonly version: string; /** Individual operation benchmarks. */ readonly operations: readonly OperationBenchmark[]; /** Environment information. */ readonly environment: BenchmarkEnvironment; /** Overall summary. */ readonly summary: BenchmarkSummary; } /** * Benchmark environment information. */ interface BenchmarkEnvironment { /** Node.js version. */ readonly nodeVersion: string; /** Platform. */ readonly platform: string; /** Architecture. */ readonly arch: string; /** CPU model. */ readonly cpuModel: string; /** CPU cores. */ readonly cpuCores: number; /** Total memory in bytes. */ readonly totalMemory: number; } /** * Benchmark summary. */ interface BenchmarkSummary { /** Total benchmark duration in milliseconds. */ readonly totalDurationMs: number; /** Total operations run. */ readonly totalOperations: number; /** Overall throughput. */ readonly overallThroughput: number; /** Average p95 latency across operations. */ readonly avgP95Latency: number; /** Pass/fail status based on thresholds. */ readonly passed: boolean; /** Failures if any. */ readonly failures: readonly string[]; } /** * Configuration for running benchmarks. */ interface BenchmarkConfig { /** Dataset sizes to test. */ readonly datasetSizes: readonly number[]; /** Number of warmup iterations. */ readonly warmupIterations: number; /** Number of measurement iterations per size. */ readonly measurementIterations: number; /** Timeout per operation in milliseconds. */ readonly timeoutMs: number; /** Thresholds for pass/fail. */ readonly thresholds: BenchmarkThresholds; } /** * Pass/fail thresholds. */ interface BenchmarkThresholds { /** Maximum acceptable p95 latency in milliseconds. */ readonly maxP95LatencyMs: number; /** Minimum acceptable throughput (ops/sec). */ readonly minThroughput: number; /** Maximum acceptable memory usage in bytes. */ readonly maxMemoryBytes: number; /** Minimum precision for retrieval (0-1). */ readonly minPrecision?: number; /** Minimum recall for retrieval (0-1). */ readonly minRecall?: number; } /** * Default benchmark configuration. */ declare const DEFAULT_BENCHMARK_CONFIG: BenchmarkConfig; /** * Multi-Agent Development Pipeline (#1684) * * Orchestrates the full development workflow with iterative loops: * * 1. RESEARCH — research expert gathers context * 2. PLAN+VOTE — architect plans, consensus votes, iterate on feedback * 3. DECOMPOSE — PM splits approved plan into phases/epics/issues * 4. IMPLEMENT — code experts work assigned tasks in parallel * 5. QA REVIEW — QA expert reviews, sends back to PM if issues found * 6. SECURITY — SARIF scan blocks on critical/high findings * 7. SHIP — all gates passed * * Each stage can iterate: vote feedback loops back to plan, * QA failures loop back to implementation via PM reassignment. * * @module pipeline/dev-pipeline */ /** Agent roles used in the pipeline. */ type PipelineRole = 'researcher' | 'architect' | 'pm' | 'coder' | 'qa' | 'security'; /** A task decomposed by the PM, potentially with conditional approval requirements. */ interface PipelineTask { readonly id: string; readonly title: string; readonly description: string; readonly assignedTo: PipelineRole; readonly status: 'pending' | 'in_progress' | 'review' | 'done' | 'rejected'; readonly feedback?: string; /** Implementation text from the code expert (surfaced for harness use). */ readonly implementation?: string; /** Conditions required for task completion (from conditional_go vote). */ readonly conditions?: readonly string[] | undefined; /** Caveats/warnings associated with the task (from conditional_go vote). */ readonly caveats?: readonly string[] | undefined; /** * #3234: deterministic research-maturity `[0,1]` of the run that produced this * task, attached after decompose. RECORDED on the routing outcome and measured * (the gated live-routing use is #3815). Absent → treated as no-research (0). */ readonly researchMaturity?: number | undefined; } /** Vote result from consensus — discriminated union with conditional approval support. */ type VoteResult = { readonly kind: 'approved'; readonly approvalPercentage: number; } | { readonly kind: 'rejected'; readonly feedback: string; readonly approvalPercentage: number; } | { readonly kind: 'conditional_go'; readonly conditions: readonly string[]; readonly caveats: readonly string[]; readonly approvalPercentage: number; } | { readonly kind: 'no_quorum'; readonly reason: string; readonly approvalPercentage: number; }; /** * What portion of the implementation a QA review actually consumed. * * Lives here rather than in `agent-executor` so the dependency stays one-way * (agent-executor imports this module, never the reverse). */ interface QaReviewCoverage { /** Characters of the implementation the reviewer was shown. */ readonly reviewedChars: number; /** Characters in the full implementation. */ readonly totalChars: number; /** True when the reviewer saw less than the whole artifact. */ readonly partial: boolean; } /** QA review result. */ interface QaReviewResult { readonly verdict: 'pass' | 'needs_work' | 'reject'; readonly feedback: string; readonly issues: readonly string[]; /** * Portion of the implementation the reviewer actually consumed. ABSENT when * the whole artifact was reviewed; present with `partial: true` when the * implementation exceeded the prompt budget. Without this the verdict was * byte-identical for a 500-char and a 500,000-char implementation (#4140 * shape, applied to QA). */ readonly coverage?: QaReviewCoverage; } /** Overall pipeline result. */ interface DevPipelineResult { /** * Whether the pipeline completed successfully. * * True only when every planned task is present in `tasks` with status 'done' * AND the security gate passed (#5645). */ readonly completed: boolean; readonly plan: string; readonly tasks: readonly PipelineTask[]; readonly voteIterations: number; readonly qaIterations: number; /** * Whether the security gate passed. * * Read together with {@link DevPipelineResult.securityRan} (#4772): `false` * with `securityRan: false` means no scan produced a measured verdict and is * NOT a failed security review. */ readonly securityPassed: boolean; /** * Whether the security gate actually ran (#4772). * * Set on every path `runDevPipeline` can return through, so * `securityPassed: false` is always readable as verdict-vs-absence. Four * paths report `false`: a dry run (plan+vote only), harness mode (tasks are * handed back for external implementation), a red quality gate in `blocking` * mode, and a security scan that returned `skip`. Only a post-scan `pass` or * `fail` verdict reports `true`. * * Absent means the producer predates the distinction (#4782), not that the * scan's status is unknown — treat an absent value as unmeasured, not `false`. */ readonly securityRan?: boolean; /** Security-stage feedback explaining why a skipped scan did not run. */ readonly securityNote?: string; /** * Terminal planning-gate state. Absent means the panel approved a usable plan. * `'empty'` means the planner returned nothing; `'no_quorum'` means the retry * budget ended without a valid panel; `'unapproved'` means every permitted * revision was rejected. Every present state stops before implementation. */ readonly planStatus?: 'empty' | 'no_quorum' | 'unapproved'; /** Last quorum failure reason when {@link planStatus} is `'no_quorum'`. */ readonly planVoteReason?: string; /** Last panel approval percentage for a terminal plan-vote outcome. */ readonly planVoteApprovalPercentage?: number; /** Last rejection feedback when {@link planStatus} is `'unapproved'`. */ readonly planVoteFeedback?: string; /** * Whether this run stopped after plan+vote because the caller asked it to. * * `completed: false` alone cannot distinguish "the pipeline failed" from "the * pipeline did exactly what was requested and stopped" — and a consumer that * reads `completed` as the verdict reports a successful dry run as an engine * fault. Absent means a normal run. */ readonly dryRun?: true; /** * Present only for `mode: 'harness'` runs. Absent means a normal run. * * The second legitimate `completed: false`, and it had no marker while the * dry run had one (#5888). Harness mode hands the tasks back for external * implementation and stops on purpose — exactly the distinction * {@link DevPipelineResult.dryRun} exists to make, so a consumer reading * `completed` as the verdict reported a successful harness run as an engine * fault. `run_dev_pipeline`'s async job status is that consumer. */ readonly harnessMode?: true; /** * Aggregate completion status of planned tasks (#5645). * * `'all_done'` when every planned task was implemented and passed QA; * `'partial'` when some but not all tasks completed with status `'done'`; * `'none'` when zero tasks completed with status `'done'` (including empty * plans where nothing was planned). * * Optional so early-return shapes that never ran the implement loop need not * carry it. */ readonly taskStatus?: 'all_done' | 'partial' | 'none'; } /** Pluggable stage implementations — inject real or mock agents. */ interface DevPipelineStages { /** * Research expert gathers context for the task. Returns the full * {@link ResearchContext} (#3234 seam 0): `.text` feeds plan/vote as before, * `.metadata` is attached to decomposed tasks for routing-experience enrichment. */ research(task: string): Promise; /** Architect creates a plan from research + task. */ plan(task: string, research: string, priorFeedback?: string): Promise; /** * Consensus vote on the plan. Returns approval + feedback. `research` is the * research-stage context, surfaced to voters so they can weigh research * maturity (#3258) — appended to the proposal as informational, untrusted * text (never as instructions). */ vote(plan: string, research: string): Promise; /** PM decomposes approved plan into tasks. */ decompose(plan: string): Promise; /** Code expert implements a task. Returns the work product. */ implement(task: PipelineTask): Promise; /** QA expert reviews implementation. */ qaReview(task: PipelineTask, implementation: string): Promise; /** * Local QA quality gate (typecheck/lint/tests/build) run before ship (#3356). * Optional: pipelines that don't supply it simply skip the gate. Returns * `passed` plus actionable `feedback` from the underlying `runQualityGate` * engine. Whether a red gate fails the phase is governed by the * `qualityGate` mode in {@link DevPipelineOptions}, not this method. */ qualityGate?(): Promise<{ passed: boolean; feedback: string; }>; /** * Security scan. `verdict` preserves the scanner's tri-state so a `skip` * (scanner absent or errored) is not recorded as a rejection (#5502). * Optional so stage implementations that predate the field still satisfy * the contract; when absent, `passed` is read as a measured pass/fail. */ securityScan(): Promise<{ readonly passed: boolean; readonly verdict?: 'pass' | 'fail' | 'skip'; readonly feedback: string; }>; } /** Pipeline execution mode. */ type PipelineMode = 'autonomous' | 'harness'; /** * Local quality-gate mode (#3356). Controls the pre-ship typecheck/lint/tests/build gate: * - 'off' (default): the gate is never run. Safe for repos lacking standard scripts. * - 'advisory': the gate runs and its feedback is recorded, but a red gate does * NOT fail the pipeline. * - 'blocking': a red gate fails the phase, the same way a blocking security * scan does. */ type QualityGateMode = 'off' | 'advisory' | 'blocking'; /** Options for pipeline execution. */ interface DevPipelineOptions { /** Session ID for checkpoint/resume. Omit for no persistence. */ readonly sessionId?: string | undefined; /** When true, stop after plan+vote and return partial result (#1717). */ readonly dryRun?: boolean | undefined; /** * Pipeline mode (#1704): * - 'autonomous' (default): full pipeline runs internally * - 'harness': stops after decompose, returns tasks for external implementation */ readonly mode?: PipelineMode | undefined; /** * Local pre-ship quality-gate mode (#3356). Default 'off' so the pipeline * never wedges repos that lack standard build/test scripts. See * {@link QualityGateMode}. Requires `stages.qualityGate` to be supplied; * if the stage is absent the gate is skipped regardless of mode. */ readonly qualityGate?: QualityGateMode | undefined; /** * Cap on plan→vote rounds (#4939). Omitted uses {@link MAX_VOTE_ITERATIONS}. * * The MCP tool has advertised `maxVoteIterations` since it shipped — bounds * checked, defaulted to 3, described in the generated tool reference — and * nothing read it, so setting it changed nothing. */ readonly maxVoteIterations?: number | undefined; /** Cap on implement→QA rounds (#4939). Omitted uses {@link MAX_QA_ITERATIONS}. */ readonly maxQaIterations?: number | undefined; /** Optional BeliefMemory for hindsight updates after plan outcomes (#1720). */ readonly beliefMemory?: IHindsightBeliefMemory | undefined; /** * Fail-closed guard invoked at the RESEARCH stage — the untrusted-read * chokepoint (#3643). The auto-remediation enforce path (#3618) wires this to * `CapabilityLedger.assertCapability('untrusted-input')`, so running the * untrusted research stage inside the write+secrets IMPLEMENT phase throws * (Rule-of-Two). Not called when {@link researchOverride} is set (no untrusted * read happens). Default: undefined (no guard — normal pipeline behavior). */ readonly untrustedInputGuard?: (() => void) | undefined; /** * Pre-seeded research text (#3643). When set, the RESEARCH stage uses this * instead of calling `stages.research()` — so the IMPLEMENT phase can run the * pipeline plan-only (from the typed RemediationPlan) with NO fresh untrusted * read, while {@link untrustedInputGuard} still fail-closes any code path that * forgets to seed it. */ readonly researchOverride?: string | undefined; /** * Content-provenance trust tier ('1'–'4') threaded into the consensus→execute * policy snapshot (#3712). Trust here is about the PROVENANCE of the content * that reached this run (the goal/research), not the caller's identity. The MCP * `run_dev_pipeline` handler and the `run` entry point thread the caller's real * `RequestContext.trustTier`; the auto-remediation IMPLEMENT path may pass `'1'` * only because #3643's typed RemediationPlan + CapabilityLedger confine * untrusted input upstream. **When undefined the seam behaves as before * (#3704): the engine defaults the missing tier to untrusted (4), fail-closed.** * Absence anywhere = untrusted; never infer a trusted tier from missing context. */ readonly trustTier?: string | undefined; /** * Durable, hash-chained audit logger (#3710). When supplied (the MCP server * threads its single startup `auditLogger`), the consensus→execute policy gate * ALSO persists each `policy.evaluated` decision to the immutable store — * carrying mode/ruleIds/stageType — so warn-mode soak evidence survives process * exit and feeds the tune/readiness loop. MUST be the server's single instance, * not a competing FileAuditStorage (shared hash chain). When undefined (pure-CLI * path), behavior is unchanged — the in-memory bus emit is the only sink. */ readonly auditLogger?: IAuditLogger | undefined; } /** * Execute the full multi-agent development pipeline. * * When `sessionId` is provided, each stage checkpoints to disk. On crash, * re-running with the same sessionId resumes from the last completed stage. * * @param task - High-level task description * @param stages - Pluggable stage implementations * @param options - Pipeline options (sessionId for checkpoint/resume) * @returns Pipeline result with all outputs */ declare function runDevPipeline(task: string, stages: DevPipelineStages, options?: DevPipelineOptions): Promise; /** * nexus-agents/mcp - Improvement Review: GitHub issue filing * * The filing step of `improvement_review` (#2402): gated on `fileIssues`, * rate-limited, deduped against open issues, command-injection-safe. This is * the ONLY module of the improvement-review family that shells out to `gh` — * `improvement-review.ts` keeps signal detection and never spawns a process. * * Moved verbatim out of `improvement-review.ts` (#6148, row 2). Only what that * file consumes is exported: the `gh` seam, the two response types and the * `maybeFileIssues` entry point; everything else is reached through it. * * @module mcp/tools/improvement-review-issue-filing */ /** Where the filed issues went, and how that target was chosen (#6112). */ interface IssueTarget { /** `owner/repo`, or null when neither the caller nor the cwd remote named one. */ readonly repo: string | null; /** * `input` — the caller passed `targetRepo`; `cwd-remote` — resolved via * `gh repo view` from the working directory; `unresolved` — the lookup * failed, so `gh` was left to its own cwd resolution (no `--repo` flag); * `not-filing` — `fileIssues` was false, nothing was resolved. */ readonly source: 'input' | 'cwd-remote' | 'unresolved' | 'not-filing'; } /** One filed issue plus what happened to its requested labels (#6112). */ interface FiledIssue { readonly signalKey: string; readonly issueUrl: string; /** Requested labels the target repo does not have; explicit `[]` when none. */ readonly labelsDropped: readonly string[]; /** * `ok` — `gh label list` answered and the filter above is real; * `unavailable` — the list failed, so the issue was filed with NO labels and * every requested label is in `labelsDropped`; * `truncated` — the list filled its page ({@link LABEL_LIST_LIMIT}), so a * label past it cannot be told from a missing one: no filtering was done, * every requested label was passed and `labelsDropped` is `[]`. * The lookup never blocks the signal. */ readonly labelCheck: 'ok' | 'unavailable' | 'truncated'; } /** * nexus-agents/mcp - Improvement Review Tool * * Periodic, threshold-gated observability-driven improvement loop. * * Reads from existing observability primitives (OutcomeStore, weather-report, * fitness-audit, audit-chain) and surfaces patterns that cross documented * thresholds as candidate GitHub issues. Never auto-merges; humans or * `consensus_vote` decide what to implement. * * Replaces the deleted `src/workflows/self-development/` engine, which never * wired up to consume any of these signals. * * This module detects signals and never spawns a process; the `gh` issue * filing lives in `improvement-review-issue-filing.ts` (#6148). * * @module mcp/tools/improvement-review * (Source: Issue #2402) */ declare const ImprovementReviewInputSchema: z.ZodObject<{ lookbackDays: z.ZodDefault>; fileIssues: z.ZodDefault>; minSampleSize: z.ZodDefault>; fitnessFloor: z.ZodDefault>; selfEvalReportPath: z.ZodOptional; targetRepo: z.ZodOptional; }, z.core.$strip>; type ImprovementReviewInput = z.infer; type SignalCategory = 'routing' | 'tech-debt' | 'bug' | 'security' | 'consensus' | 'tool-fitness' | 'perf-regression'; interface ImprovementSignal { readonly category: SignalCategory; /** Stable key used for dedup against existing issues. */ readonly signalKey: string; /** Severity per CVSS-aligned scale (security uses critical; others use warning/info). */ readonly severity: 'info' | 'warning' | 'critical'; /** One-line title suitable for a GitHub issue. */ readonly title: string; /** Multi-line body with evidence (sample counts, time windows, observed values). */ readonly body: string; /** Linkable evidence the signal is grounded in observability data, not intuition. */ readonly evidence: { readonly samples?: number; readonly window?: string; readonly observedValue?: number; readonly threshold?: number; }; } interface ImprovementReviewResponse { readonly window: string; readonly totalOutcomes: number; readonly signals: readonly ImprovementSignal[]; /** * Remediation tasks derived from {@link signals} (#3540 capability-loop * increment 1) — SUGGEST-ONLY: structured tasks for a reviewer to consider * routing through the dev-pipeline. Nothing here is executed or auto-invoked. */ readonly remediationTasks: readonly PipelineTask[]; /** Filed issues, each with the labels the target repo lacked (#6112). */ readonly issuesFiled: readonly FiledIssue[]; readonly issuesSkipped: readonly { readonly signalKey: string; readonly reason: string; }[]; /** Where the issues went and how the target was chosen; `not-filing` when fileIssues=false. */ readonly issueTarget: IssueTarget; } type ImprovementReviewDeps = BaseMcpToolDeps; /** @category MCP */ declare function registerImprovementReviewTool(server: McpServer, deps: ImprovementReviewDeps): void; /** * nexus-agents/mcp - Weather Report MCP Tool * * Read-only MCP tool that returns per-CLI, per-category performance * data and adaptive routing bonuses from the OutcomeStore. * * @module mcp/tools/weather-report-tool * (Source: Issue #865 — Weather report with adaptive routing) */ type WeatherReportDeps$1 = BaseMcpToolDeps; /** @category MCP */ declare function registerWeatherReportTool(server: McpServer, deps: WeatherReportDeps$1): void; /** * nexus-agents/orchestration - Strategy Manifest schema + loader. * * The strategy-manifest registry (`governance/strategy-manifests.yaml`) is the * single source of truth describing each routable execution strategy: which * engine fronts it, whether it has a wired executor, when to force it, and the * forward-compat governance (authority tier — Epic D) and cost (Epic G) fields. * The MetaOrchestrator routes purely over manifest data — adding a capability * becomes "register a manifest", not "edit the router" (Epic C, #3833). * * This module owns ONLY the schema + loader/validator (child #3834). It MIRRORS * the claims-registry pattern (versioned YAML + Zod schema + loader + Vitest) so * a reviewer reasons about both with the same mental model. * * Explicitly deferred to siblings: * - #3835: migrating the 8 live strategies (`STRATEGY_ENTRYPOINT_TOOL`, * run-tool.ts) to registered manifests + the behaviour-parity golden test. * - #3836: the router refactor that consumes these manifests instead of the * hardcoded `decideStrategy` rules. * - #3837: drift-gating the registry under `governance:check`. * * @module orchestration/strategy-manifest * (Source: Issue #3833, #3834) */ /** * Cost profile (Epic G, #3856). A coarse cost hint scaled by a strategy's * fan-out: `low` (one model call), `medium` (templated multi-stage gate), `high` * (N-voter panel / multi-agent orchestration / greenfield build), `variable` * (spend scales with input size — graph topology, research breadth). Populated * for the live 8 manifests by #3856 and surfaced in the weather_report cost * section alongside the measured per-decision aggregates (#3855). Stays optional * on the schema so a future manifest can register before grading its profile. */ declare const CostProfileSchema: z.ZodEnum<{ high: "high"; low: "low"; medium: "medium"; variable: "variable"; }>; type CostProfile = z.infer; /** * Pipeline Stage Types — Shared interfaces for graph-backed pipelines (#1735, Phase 2) * * Defines the IPipelineStage interface that all pipeline stages implement. * Stages are wrapped as GraphBuilder NodeHandlers for execution. * * @module pipeline/stage-types */ /** Read-only pipeline context passed to every stage. */ interface PipelineContext { /** Unique pipeline execution ID. */ readonly executionId: string; /** The original task/prompt that started the pipeline. */ readonly task: string; /** Pipeline template being executed. */ readonly templateId: string; /** * Accumulated state from prior stages. The only cross-stage handoff * channel — `sharedMemory` (the #1764 SharedMemoryStore) was removed * in #2937 after being write-only since introduction. If you need * structured cross-stage data, add a well-known key to * `PIPELINE_STATE_KEYS` and write/read through `state`. */ readonly state: Readonly>; } /** Result of executing a single pipeline stage. */ interface StageOutput { /** The key to store this stage's output under in pipeline state. */ readonly stateKey: string; /** The output value (stored in GraphState). */ readonly value: unknown; /** Duration in milliseconds. */ readonly durationMs: number; /** Whether the stage succeeded. */ readonly success: boolean; /** Error message if failed. */ readonly error?: string | undefined; } /** A pipeline stage that can be compiled into a graph node. */ interface IPipelineStage { /** Unique stage identifier (used as graph node ID). */ readonly id: string; /** Human-readable stage name. */ readonly name: string; /** Execute the stage. */ execute(context: PipelineContext): Promise; } /** Edge definition in a pipeline template. */ type PipelineEdge = { readonly type: 'fixed'; readonly from: string; readonly to: string; } | { readonly type: 'conditional'; readonly from: string; readonly routerKey: string; readonly targets: readonly string[]; }; /** A declarative pipeline template defining stages and their connections. */ interface PipelineTemplate { /** Unique template identifier. */ readonly id: string; /** Human-readable name. */ readonly name: string; /** Ordered stage IDs (for simple linear pipelines). */ readonly stages: readonly string[]; /** Edge overrides (for non-linear flows like vote→plan feedback loops). */ readonly edges?: readonly PipelineEdge[] | undefined; /** Stage IDs that can be skipped via dryRun. */ readonly dryRunStopAfter?: string | undefined; } /** Standard state keys used across pipeline templates. */ declare const PIPELINE_STATE_KEYS: { readonly TASK: "task"; readonly RESEARCH: "research"; readonly PLAN: "plan"; readonly VOTE_RESULT: "voteResult"; readonly VOTE_FEEDBACK: "voteFeedback"; readonly VOTE_ITERATIONS: "voteIterations"; readonly TASKS: "tasks"; readonly IMPLEMENTATIONS: "implementations"; readonly QA_ITERATIONS: "qaIterations"; readonly SECURITY_PASSED: "securityPassed"; readonly FINDINGS: "findings"; readonly PARSED_SPEC: "parsedSpec"; readonly SCAFFOLD_OUTPUT: "scaffoldOutput"; readonly COMPLETED: "completed"; }; /** * Pipeline Graph Compiler — Build executable graphs from templates (#1735, Phase 2) * * Compiles a PipelineTemplate + IPipelineStage implementations into a * CompiledGraph that can be executed by the GraphExecutor. * * @module pipeline/pipeline-graph */ /** Result of compiling a pipeline template into a graph. */ interface PipelineGraphResult { readonly ok: boolean; readonly graph?: CompiledGraph | undefined; readonly error?: string | undefined; } /** Map of stage ID → stage implementation. */ type StageRegistry = ReadonlyMap; /** * Compile a pipeline template + stages into an executable graph. * * Each IPipelineStage is wrapped as a GraphBuilder node handler. * Linear edges are auto-generated from template.stages order. * Custom edges override the linear flow for feedback loops. */ declare function compilePipelineGraph(template: PipelineTemplate, stages: StageRegistry): PipelineGraphResult; /** * Graph Pipeline Runner — Execute pipelines via GraphBuilder (#1735, Phase 2) * * Provides a runGraphPipeline() function that compiles a PipelineTemplate * + stage registry into an executable graph and runs it through the * graph executor with checkpoint/resume support. * * @module pipeline/graph-pipeline-runner */ /** Options for graph-based pipeline execution. */ interface GraphPipelineOptions { /** When true, stop after the dryRunStopAfter stage. */ readonly dryRun?: boolean | undefined; /** * Maximum graph node executions (default: 20). Parallel super-steps are * atomic and start only when their full batch fits in the remaining budget. */ readonly maxSteps?: number | undefined; } /** Result of a graph-based pipeline execution. */ interface GraphPipelineResult { readonly success: boolean; readonly templateId: string; readonly stepsExecuted: number; readonly durationMs: number; readonly finalState: Readonly>; readonly error?: string | undefined; /** * Set when the run was a dry run. Mirrors `DevPipelineResult.dryRun`: a * consumer reading `success` alone reported a truncated dry run as a full * pipeline. Absent means a normal run. */ readonly dryRun?: true; /** * Stages the template declares, and stages this run actually executed. * * `templateId` names the FULL template even when `resolveEffectiveTemplate` * truncated it at `dryRunStopAfter`, so `templateId: 'dev'` with * `success: true` used to be byte-identical whether qa and security ran or * were sliced away. These two numbers are what makes the coverage legible * without the consumer having to know `dryRunStopAfter` and the stage list. */ readonly stagesPlanned: number; readonly stagesRun: number; } /** * Run a pipeline using graph-based execution. * * Compiles the template + stages into a graph, then executes via * the graph executor (super-step BSP model). */ declare function runGraphPipeline(task: string, template: PipelineTemplate, stages: StageRegistry, options?: GraphPipelineOptions): Promise; /** * Reads one key out of the final pipeline state. * * UNTYPED, which the header above used to deny — it promised "typed access to * well-known state keys" (#5771). The well-known keys do exist * (`PIPELINE_STATE_KEYS` in `stage-types.ts`), but this function does not use * them: `key` is a bare `string`, so a typo compiles, and the return is * `unknown`, so every caller narrows it itself. Narrowing the parameter to * `(typeof PIPELINE_STATE_KEYS)[keyof typeof PIPELINE_STATE_KEYS]` would make * the old header true, but this is published API and that is a breaking * change — queued with the next-major batch rather than done here. * * Returns `undefined` for a key the run never set, which is indistinguishable * from a key set to `undefined`; a caller needing to tell those apart must * inspect the state object directly. Falsy values come back as themselves. * * Published (`exports/pipeline.ts`) and, as of #5771, with no consumer at all * — not even a test. These assertions exist so the behaviour is pinned rather * than merely exported. */ declare function extractStateValue(state: Readonly>, key: string): unknown; /** * Adaptive Orchestrator — Task-driven pipeline selection (#1736, Phase 3) * * Analyzes incoming tasks, selects the appropriate pipeline template, * and executes via the graph pipeline runner. Single entry point * for all pipeline types. * * Design pattern: deterministic state machine backbone + selective * LLM invocation at decision nodes only (per CrewAI Flows / Temporal). * * `classifyTask` is a task classifier — one of 5 INTENTIONALLY SEPARATE classifiers * (see #3299, by-design). This one: `PipelineType` (5-value: dev/research/audit/greenfield/ * general) → pipeline-stage selection. Distinct from: shared-task-analyzer (9-category * capability routing), task-type-classifier (reasoning|knowledge protocol selection), * cli-adapters/task-classifier (CLI fallback-chain ordering), coordination/task-features * (scaling topology). Keyword overlap is superficial — the same token routes differently per * layer and the output enums are incompatible, so these are NOT consolidated. See #3299. * * @module pipeline/adaptive-orchestrator * (Source: Issue #1736; Issue #3299) */ /** Options for the adaptive orchestrator. */ interface AdaptiveOrchestratorOptions extends GraphPipelineOptions { /** Force a specific template (skip auto-detection). */ readonly templateId?: string | undefined; /** Stage registry to use. If omitted, stages must be provided per-template. */ readonly stages: StageRegistry; } /** Result of adaptive orchestration — extends GraphPipelineResult with metadata. */ interface AdaptiveOrchestratorResult extends GraphPipelineResult { /** How the template was selected. */ readonly selectionMethod: 'explicit' | 'auto-detected'; /** Task classification used for selection. */ readonly taskClassification: TaskClassification; } /** Classification of a task for template routing. */ interface TaskClassification { readonly pipelineType: PipelineType; readonly complexity: 'simple' | 'moderate' | 'complex'; readonly confidence: number; readonly keywords: readonly string[]; } /** Pipeline type derived from task analysis. */ type PipelineType = 'dev' | 'research' | 'audit' | 'greenfield' | 'general'; /** Classify a task for pipeline routing. */ declare function classifyTask(task: string): TaskClassification; /** * Run the adaptive orchestrator — classify task, select template, execute. * * This is the single entry point for all pipeline execution. */ declare function runAdaptiveOrchestrator(task: string, options: AdaptiveOrchestratorOptions): Promise; /** * nexus-agents/orchestration - Workflow Pattern Router * * Intelligent orchestration pattern selection based on task characteristics. * Uses SharedTaskAnalyzer signals + caller hints to select the optimal * workflow pattern (sequential, wave, graph, consensus, aflow, puppeteer). * * v1: Rule-based only (per consensus vote — no ML/RL yet). * * @module orchestration/workflow-router * (Source: Issue #844 — Intelligent Workflow Pattern Router) */ /** * Creates a workflow pattern router. * * Analyzes task characteristics and selects the optimal orchestration * pattern using a rule-based classification system. * * Scope of `recordOutcome` / `getMetrics` (#2824): the recorded * `PatternOutcome`s live in a buffer owned by this router instance. * `route()` is a deterministic, rule-based classifier — it does NOT * consume recorded outcomes, so there is no per-instance learning to * "lose", and nothing to aggregate across processes. The pair is an * observability surface only. If cross-process pattern metrics are * ever needed, add a dedicated consumer that writes to a shared * `OutcomeStore` rather than widening this router's responsibility. */ declare function createWorkflowRouter(options?: { readonly logger?: ILogger | undefined; readonly analyzer?: ISharedTaskAnalyzer | undefined; }): IWorkflowRouter; /** Public interface for the workflow router. */ interface IWorkflowRouter { /** Routes a task to the optimal workflow pattern. */ route(signals: TaskSignals, options?: WorkflowRouterOptions): RoutingDecision$1; /** * Records an execution outcome into this router instance's buffer. * Observability only — `route()` never reads it back (#2824). */ recordOutcome(outcome: PatternOutcome): void; /** Aggregates this instance's recorded outcomes, optionally filtered by pattern. */ getMetrics(pattern?: WorkflowPattern): readonly PatternMetrics[]; } /** * nexus-agents/orchestration - MetaOrchestrator (adaptive selection tier) * * One adaptive entry point that, given a goal, SELECTS the right execution * strategy among the existing specialized pipelines — it routes once per task, * it does NOT switch patterns mid-flight and it does NOT execute anything * itself. This is the "routing" pattern (Anthropic, Building Effective Agents): * classify → dispatch to a specialized pipeline, rather than a generalist * mega-pipeline. * * Step 1 (#3549) is a pure, deterministic selection function. It reuses the * existing selection brains — `SharedTaskAnalyzer` (signals), `WorkflowRouter` * (execution pattern), and `classifyTask` (pipeline template) — and maps their * combined output to a single {@link ExecutionStrategy}. Dispatch wiring, * decision logging, and learned selection are later steps of epic #3548. * * @module orchestration/meta-orchestrator * (Source: Issue #3549 — MetaOrchestrator step 1) */ /** * Execution strategies the MetaOrchestrator can select. Each maps to an * existing entry point / engine — the MetaOrchestrator does not introduce a * new execution path, it chooses among the ones that already exist. */ type ExecutionStrategy = /** Trivial single-step task → `delegate_to_model`. */ 'single-shot' /** Code change with the dev gate (test/lint/typecheck) → `run_dev_pipeline`. */ | 'dev-pipeline' /** Multi-stage templated work (audit/general) → `run_pipeline`. */ | 'pipeline' /** DAG / conditional-edge workflow → `run_graph_workflow`. */ | 'graph-workflow' /** Pattern-based multi-agent orchestration (wave/aflow/puppeteer) → `orchestrate`. */ | 'orchestrate' /** Multi-perspective decision → `consensus_vote`. */ | 'consensus' /** Greenfield project from a spec → `execute_spec`. */ | 'spec' /** Research-heavy work → the research pipeline. */ | 'research'; /** * nexus-agents/orchestration - Strategy manifest registry (the live 8 manifests). * * The runtime source of truth for the eight routable execution strategies. This * REPLACES the former hardcoded `STRATEGY_ENTRYPOINT_TOOL` map in run-tool.ts * (#3835): the entrypoint-tool and executor-availability lookups the run path * needs are now DATA, read from a validated manifest registry rather than a * literal map embedded in the tool layer. * * The manifests are embedded here as a typed constant (no disk I/O on the MCP * hot path) and validated through {@link parseStrategyManifestRegistry} AT MODULE * LOAD — a malformed registry fails closed at import time, exactly as the * disk-loaded path would. The companion `governance/strategy-manifests.yaml` is * the human-facing / docs source of truth (#3838) and the drift-gate target * (#3837); `strategy-manifest-registry.test.ts` asserts the two are equal so * they cannot diverge. * * Out of scope (deferred): the selection-logic refactor that routes PURELY over * this data — `decideStrategy` in meta-orchestrator.ts — is #3836. This module * only relocates the entrypoint/executor lookups off the hardcoded map. * * @module orchestration/strategy-manifest-registry * (Source: Issue #3833, #3835 — schema landed via #3834) */ /** One strategy's declared cost profile, for the weather_report cost section (#3856). */ interface StrategyCostProfileEntry { readonly strategy: ExecutionStrategy; readonly entrypointTool: string; /** The declared coarse cost hint; undefined for any manifest not yet populated. */ readonly costProfile: CostProfile | undefined; } /** * Type definitions for the Weather Report MCP tool. * * Surfaces observed model performance as a living "weather report" * and computes adaptive routing bonuses from outcome data. * * @module mcp/tools/weather-report-types * (Source: Issue #865 — Weather report with adaptive routing) */ declare const WeatherReportInputSchema: z.ZodObject<{ cli: z.ZodOptional>; category: z.ZodOptional>; includeAdaptive: z.ZodDefault>; }, z.core.$strip>; /** Options for generateWeatherReport (all fields optional). */ interface WeatherReportOptions { readonly cli?: CliNameLiteral; readonly category?: string; readonly includeAdaptive?: boolean; /** * Opt-in for the per-model telemetry lens (#4194). Default off (#4202): * the lens scans the full store per distinct model, so the hot * routing-bonus path (weather-bonus-stage) must not pay for it; the * weather_report MCP tool always opts in. */ readonly includeModelWeather?: boolean; } /** Adapter attempt stats separating infra failures from model-quality failures (#1982). */ interface AdapterAttemptStats { /** * Success rate excluding adapter_unavailable failures. Represents model-quality * success when the adapter could actually attempt the task. Rounded to 3 decimals. */ readonly adapterAttemptSuccessRate: number; /** Count of adapter_unavailable failures in the sample. */ readonly adapterUnavailableCount: number; /** * Fraction of total attempts that failed due to adapter_unavailable. Rounded * to 3 decimals. Useful for comparing infra availability across CLIs/categories. */ readonly adapterUnavailableRate: number; } /** Per-CLI performance stats in the weather report. */ interface CliWeather extends AdapterAttemptStats { readonly cli: string; readonly totalTasks: number; readonly successRate: number; readonly avgDurationMs: number; readonly byCategory: ReadonlyMap; } /** Adaptive bonus for a CLI+category pair. */ interface AdaptiveBonus { readonly cli: string; readonly category: TaskCategory; readonly staticBonus: number; readonly adaptiveBonus: number; readonly sampleCount: number; readonly sufficient: boolean; } /** * Per-model performance lens entry (#4194). A telemetry surface computed from * the same OutcomeStore records as the CLI×category bonuses, keyed by concrete * model id via the #2548 family-fallback query path. NOT a routing input — * adaptive bonuses stay CLI×category; per-model bonus consumption is * #4196/#4197 scope. */ interface ModelWeatherEntry { /** Concrete model id observed in outcome records. */ readonly model: string; /** Vendor resolved via the ModelRegistry (#2548). */ readonly vendor: string; /** Family resolved via the ModelRegistry (#2548). */ readonly family: string; /** * Whether the stats come from literal-id samples or the family-broadened * cold-start fallback (#2548). Family scope means sibling-model outcomes * are included as priors. */ readonly scope: 'literal' | 'family'; readonly sampleCount: number; readonly successRate: number; readonly avgDurationMs: number; } /** Tier recommendation surfaced in the weather report (#895). */ interface TierRecommendationEntry { readonly category: string; readonly direction: 'promote' | 'demote'; readonly currentTier: number; readonly recommendedTier: number; readonly successRate: number; readonly sampleCount: number; readonly reason: string; } /** Learning insight for a CLI+category pair (Issue #901, Phase 4). */ interface LearningInsight { readonly cli: string; readonly category: TaskCategory; readonly trend: 'improving' | 'declining' | 'stable'; readonly confidence: number; readonly adjustedBaseline: number; readonly sampleCount: number; } /** Recommended CLI→category mapping for LinUCB cold-start (Epic #952, Phase 6). */ interface RecommendedMapping { readonly category: TaskCategory; readonly recommendedCli: string; readonly successRate: number; readonly sampleCount: number; readonly confidence: 'high' | 'medium' | 'low'; } /** Rate limit stats per provider (Issue #996). */ interface RateLimitReport { readonly provider: string; readonly totalHits: number; readonly lastHitAt: number; readonly avgRetryAfterMs: number | undefined; } /** Per-tool performance stats (Issue #1022). */ interface ToolPerformanceEntry { readonly toolName: string; readonly totalCalls: number; readonly successRate: number; readonly avgDurationMs: number; readonly errorCount: number; } /** Failure breakdown entry for the weather report (Issue #1025). */ interface FailureBreakdownEntry { readonly category: string; readonly count: number; readonly percentage: number; } /** Per-expert-role performance stats from worker dispatch outcomes (Issue #1324, #1427). */ interface ExpertPerformanceEntry { readonly role: string; readonly totalTasks: number; readonly successRate: number; readonly avgDurationMs: number; readonly dominantErrorPattern?: string; /** Number of consecutive failures at tail of outcome history (Issue #1427). */ readonly consecutiveFailures: number; /** ISO timestamp of last successful outcome (Issue #1427). */ readonly lastSuccessAt?: string; /** True when successRate < 0.5 — signals operator attention needed (Issue #1427). */ readonly degraded: boolean; } /** Agent health summary from heartbeat monitor (Issue #1032). */ interface AgentHealthSummary { readonly activeSessions: number; readonly stalledSessions: number; /** * Sessions that have reported no progress yet (#4665), so their silence * carries no information either way. Counted rather than listed: the * per-session `health` union below is reachable from the exported * `generateWeatherReport` return type, so adding `'unmeasured'` to it would * break downstream readers. Widening it is tracked with the other * return-position unions in #4740. * * `activeSessions - unmeasuredSessions` is the number this report can * actually speak to. */ readonly unmeasuredSessions?: number; /** Sessions with a measured health verdict. Excludes unmeasured ones. */ readonly sessions: readonly AgentSessionEntry[]; } /** Single agent session health entry. */ interface AgentSessionEntry { readonly sessionId: string; readonly expertId: string; readonly health: 'alive' | 'slow' | 'stalled'; readonly elapsedMs: number; readonly timeSinceHeartbeatMs: number; readonly heartbeatCount: number; } /** Swarm health metrics dashboard (Issue #1403, Phase 6.2). */ interface SwarmHealthMetrics { /** % of dispatched expert roles that produced at least one success. Target: 70-90%. */ readonly agentUtilization: number; /** Successful tasks / total worker dispatches. Target: > 0.1. */ readonly collaborationEfficiency: number; /** % of tasks routed to the empirically best CLI for their category. Target: > 80%. */ readonly routingAccuracy: number; /** * Avg gap between actual success rate and best-possible rate per category. * Target: decreasing. Only meaningful when {@link analyzedCategories} > 0 — * with no analysable category this is 0, which on a lower-is-better metric is * the BEST possible value rather than an absent one (#6036). */ readonly weeklyRegret: number; /** * Avg samples to reach 'high' confidence per category. Target: < 50. * Only meaningful when {@link adaptationSpeedCategories} > 0 — with no * category ever reaching confidence this is 0, i.e. the best achievable score * for a workspace that has learned nothing (#6036). */ readonly adaptationSpeed: number; /** How many categories contributed to {@link adaptationSpeed}. 0 ⇒ unmeasured. */ readonly adaptationSpeedCategories: number; /** Number of observed categories with sufficient data. */ readonly observedCategories: number; /** * Of {@link observedCategories}, how many produced a routing verdict — the * denominator {@link weeklyRegret} is actually averaged over. 0 ⇒ unmeasured. * * Distinct from `observedCategories` on purpose: a category can clear * ROUTING_MIN_SAMPLES and still be unanalysable, and counting it here * inflated the denominator and understated regret (#6036). */ readonly analyzedCategories: number; /** Number of expert roles observed. */ readonly observedRoles: number; } /** Worker failure triage statistics (#1506). */ interface TriageStats { /** Total outcomes that were retried via triage. */ readonly totalRetried: number; /** Retry success rate (retried + success / total retried). */ readonly retrySuccessRate: number; /** Breakdown by triage action. */ readonly actionBreakdown: readonly { readonly action: string; readonly count: number; }[]; } /** * Cost section of the weather report (Epic G, #3856). Answers "what do governed * decisions cost?" by surfacing the MEASURED per-decision cost aggregates * (DecisionCostStore, #3855) windowed by gate type, alongside each strategy's * coarse declared `costProfile` from the manifest registry. Both ride existing * surfaces — no new MCP tool. */ interface CostSection { /** Measured per-gate-type cost aggregates over the lookback window (#3855/#3856). */ readonly decisionCosts: DecisionCostReport; /** Each strategy's declared coarse cost profile from the manifest registry. */ readonly strategyCostProfiles: readonly StrategyCostProfileEntry[]; } /** Full weather report response. */ interface WeatherReportResponse { readonly overall: AdapterAttemptStats & { readonly totalTasks: number; readonly successRate: number; readonly avgDurationMs: number; }; readonly cliWeather: readonly CliWeather[]; readonly adaptiveBonuses: readonly AdaptiveBonus[]; /** Outcome-driven tier change recommendations (#895). */ readonly tierRecommendations: readonly TierRecommendationEntry[]; /** Adaptive learning insights per CLI+category (#901). */ readonly learningInsights?: readonly LearningInsight[]; /** Recommended CLI mappings per category for LinUCB priors (Epic #952). */ readonly recommendedMappings?: readonly RecommendedMapping[]; /** Rate limit utilization per provider (Issue #996). */ readonly rateLimits?: readonly RateLimitReport[]; /** Per-tool invocation metrics (Issue #1022). */ readonly toolPerformance?: readonly ToolPerformanceEntry[]; /** Failure breakdown by category (Issue #1025). */ readonly failureBreakdown?: readonly FailureBreakdownEntry[]; /** Agent health from heartbeat monitor (Issue #1032). */ readonly agentHealth?: AgentHealthSummary; /** Per-expert-role performance from worker dispatch outcomes (Issue #1324). */ readonly expertPerformance?: readonly ExpertPerformanceEntry[]; /** Swarm health metrics dashboard (Issue #1403). */ readonly swarmHealth?: SwarmHealthMetrics; /** Worker failure triage statistics (#1506). */ readonly triageStats?: TriageStats; /** Cost section: per-gate decision-cost aggregates + strategy cost profiles (Epic G, #3856). */ readonly costSection?: CostSection; /** * Per-model performance lens (#4194) — telemetry only; routing bonuses stay * CLI×category. Present only when at least one model clears the min-sample * threshold. */ readonly modelWeather?: readonly ModelWeatherEntry[]; /** Recent performance within the lookback window (#1401). */ readonly recentWindow?: { readonly windowMs: number; readonly totalTasks: number; readonly successRate: number; readonly avgDurationMs: number; }; readonly explorationRate: number; readonly coldStartThreshold: number; readonly collectedAt: string; } declare const WeatherReportConfigSchema: z.ZodObject<{ coldStartThreshold: z.ZodDefault; explorationRate: z.ZodDefault; maxBonusAdjustment: z.ZodDefault; outcomeLookbackMs: z.ZodDefault; }, z.core.$strip>; type WeatherReportConfig = z.infer; /** * nexus-agents/mcp - Weather Report * * Computes a living performance dashboard from task outcome data * and calculates adaptive routing bonuses using epsilon-greedy * exploration/exploitation tradeoff. * * @module mcp/tools/weather-report * (Source: Issue #865 — Weather report with adaptive routing) */ /** * Optional injectable dependencies for {@link generateWeatherReport} (#3856). * The cost section reads persisted per-decision cost records; tests inject a * deterministic set via {@link WeatherReportDeps.decisionCostRecords} rather than * touching the durable {@link DecisionCostStore}. */ interface WeatherReportDeps { /** * Pre-resolved decision-cost records to aggregate for the cost section. When * omitted, the records are read from the durable {@link DecisionCostStore} iff * persistence is enabled (no store is constructed when it is off). */ readonly decisionCostRecords?: readonly DecisionCostRecord[]; } /** * Generates the weather report from current outcome data. */ declare function generateWeatherReport(input: WeatherReportOptions, config?: Partial, deps?: WeatherReportDeps): WeatherReportResponse; /** * nexus-agents/mcp - Registry Import MCP Tool * * Generates draft ModelCapability entries for adding new models * to the canonical registry. Quality scores default to 5/10 * and require human review before routing trusts them. * * @module mcp/tools/registry-import-tool * (Source: Issue #889, Epic #888) */ type RegistryImportDeps = BaseMcpToolDeps; /** @category MCP */ declare function registerRegistryImportTool(server: McpServer, deps: RegistryImportDeps): void; /** * nexus-agents/mcp - Registry Import Types * * Input/output types for the registry_import MCP tool. * * @module mcp/tools/registry-import-types * (Source: Issue #889, Epic #888) */ declare const RegistryImportInputSchema: z.ZodObject<{ provider: z.ZodEnum<{ anthropic: "anthropic"; google: "google"; openai: "openai"; }>; modelId: z.ZodString; dryRun: z.ZodDefault>; }, z.core.$strip>; type RegistryImportInput = z.infer; /** * nexus-agents/mcp - Repository Analyze MCP Tool * * Inspects a GitHub repository and returns structured analysis * of its language, tooling, CI, security posture, and gaps. * Replaces 5-10 manual tool calls with a single structured query. * * @module mcp/tools/repo-analyze-tool * (Source: Issue #1074, 6-0 consensus vote) */ type RepoAnalyzeDeps = BaseMcpToolDeps; /** @category MCP */ declare function registerRepoAnalyzeTool(server: McpServer, deps: RepoAnalyzeDeps): void; /** * nexus-agents/mcp - Repository Analyze Types * * Input/output types for the repo_analyze MCP tool. * * @module mcp/tools/repo-analyze-types * (Source: Issue #1074) */ declare const RepoAnalyzeInputSchema: z.ZodObject<{ repo: z.ZodString; depth: z.ZodDefault>>; }, z.core.$strip>; type RepoAnalyzeInput = z.infer; /** Structured analysis of a GitHub repository. */ interface RepoAnalysis { /** Repository name with owner (e.g., "owner/repo"). */ readonly name: string; /** Primary programming language. */ readonly language: string | null; /** Detected framework (e.g., "express", "react", "spring-boot"). */ readonly framework: string | null; /** Package manager (e.g., "npm", "pip", "maven", "cargo"). */ readonly packageManager: string | null; /** CI provider (e.g., "github-actions", "concourse", "jenkins"). */ readonly ciProvider: string | null; /** Security tooling detected in the repo. */ readonly securityTooling: readonly string[]; /** Whether the repo has a Dockerfile. */ readonly hasDockerfile: boolean; /** Whether the repo has Helm charts. */ readonly hasHelmCharts: boolean; /** Whether the repo has a Makefile. */ readonly hasMakefile: boolean; /** * Whether the repo has tests. Only meaningful when {@link testsMeasured} is * true — `false` alone cannot distinguish "no tests" from "no probe for this * language" (#6018). */ readonly hasTests: boolean; /** * Whether test detection had a rule for this repo's language (#6018). * * REQUIRED, not optional, so the compiler names every producer. Before this, * `hasTests: false` was emitted for any language the JS-shaped probes did not * cover, and a Rust workspace with 1385 `#[test]` functions reported * "No test directory detected" — a default wearing the costume of a * measurement. When this is false the gap list stays silent rather than * asserting an absence nobody checked. */ readonly testsMeasured: boolean; /** * Whether `.github/workflows/` was actually listed (#6035). * * REQUIRED, not optional: an optional flag lets a construction site omit it * and inherit the confident default, which is the shape that produced the * bug. False ⇒ CI-level security tooling is unmeasured, and the SAST gap is * reported as unverified rather than asserted. */ readonly workflowsMeasured: boolean; /** License type (e.g., "MIT", "Apache-2.0"). */ readonly license: string | null; /** Repository description. */ readonly description: string | null; /** Default branch name. */ readonly defaultBranch: string; /** Star count. */ readonly stars: number; /** Top-level directory listing. */ readonly topLevelEntries: readonly string[]; /** Identified gaps or missing best practices. */ readonly gaps: readonly string[]; } /** What each secondary listing observed. Optional at the boundary, resolved once. */ interface RepoListings { readonly dotGithubEntries?: readonly string[]; readonly dotGithubListed?: boolean; readonly workflowsMeasured?: boolean; } type ExecFileFn = (cmd: string, args: string[], options?: { timeout?: number; }) => Promise<{ stdout: string; }>; /** * nexus-agents/mcp - Repository Analyze Logic * * Inspects a GitHub repository and returns structured analysis * including language, tooling, CI, security, and gap identification. * * @module mcp/tools/repo-analyze * (Source: Issue #1074) */ /** Normalize "owner/repo" from either "owner/repo" or full GitHub URL. */ declare function normalizeRepoId(input: string): string; /** GitHub repo metadata from the API. */ interface GhRepoMetadata { readonly name: string; readonly full_name: string; readonly description: string | null; readonly language: string | null; readonly default_branch: string; readonly stargazers_count: number; readonly license: { readonly spdx_id: string; } | null; } /** Analyze a GitHub repository given its metadata and file tree. */ declare function analyzeRepo(metadata: GhRepoMetadata, topLevelEntries: readonly string[], workflowEntries?: readonly string[], /** What each secondary listing observed — grouped, not four positional flags. */ listings?: RepoListings): RepoAnalysis; /** Fetch repo data from GitHub and produce analysis. */ declare function analyzeGitHubRepo(input: RepoAnalyzeInput, /** * Injected `gh` runner, so the FETCH path is testable and not only the * pure functions downstream of it (#6035). * * Without this, reverting `fetchWorkflowEntries` to report `listed: true` * on error broke no test: the flag was exercised by injecting it into * `identifyGaps` directly, while the producer that derives it had no * coverage at all. Every other fetch in this module already takes an * `ExecFileFn`; the entry point was the one place that did not. */ execOverride?: ExecFileFn): Promise; /** * nexus-agents/mcp - Repository Security Plan MCP Tool * * Generates a language-aware security scanning pipeline recommendation * by analyzing a repository and mapping it to the vulnerability scanner registry. * * @module mcp/tools/repo-security-plan-tool * (Source: Issue #1079, 3-0 consensus vote) */ type RepoSecurityPlanDeps = BaseMcpToolDeps; /** @category MCP */ declare function registerRepoSecurityPlanTool(server: McpServer, deps: RepoSecurityPlanDeps): void; /** * nexus-agents/mcp - Repository Security Plan Types * * Input/output types for the repo_security_plan MCP tool. * * @module mcp/tools/repo-security-plan-types * (Source: Issue #1079) */ declare const RepoSecurityPlanInputSchema: z.ZodObject<{ repo: z.ZodString; categories: z.ZodOptional>; maxScanners: z.ZodDefault>; }, z.core.$strip>; type RepoSecurityPlanInput = z.infer; /** A single scanner recommendation with rationale. */ interface ScannerRecommendation { readonly name: string; readonly displayName: string; readonly category: string; readonly license: string; readonly pricingModel: string; readonly rationale: string; readonly priority: 'critical' | 'recommended' | 'optional'; readonly ciSnippet: string | null; } /** A conflict or redundancy warning. */ interface ConflictWarning { readonly scanners: readonly string[]; readonly type: 'redundant' | 'superseded'; readonly recommendation: string; } /** Coverage analysis by category. */ interface CoverageAnalysis { readonly category: string; readonly covered: boolean; readonly scanners: readonly string[]; } /** Complete security scanning plan for a repository. */ interface RepoSecurityPlan { readonly repo: string; readonly language: string | null; readonly framework: string | null; readonly ciProvider: string | null; readonly existingTooling: readonly string[]; readonly recommendations: readonly ScannerRecommendation[]; readonly conflicts: readonly ConflictWarning[]; readonly coverage: readonly CoverageAnalysis[]; readonly gapsSummary: readonly string[]; /** * Where the scanner data behind this plan came from (#6037). * * REQUIRED, because the whole defect was that it could be absent: the value * was computed in `resolveScannerData` and discarded at this boundary, so a * plan built from `FALLBACK_SCANNER_DATA` — or from a cache with no age bound * — read exactly like one built against the live registry, under a tool * description promising "provenance-tracked metrics". * * `cache` is deliberately distinct from `registry`: `CACHE_TTL_MS` gates only * whether to REFETCH, so the stale-cache path returns an entry of any age. */ readonly scannerDataSource: 'registry' | 'cache' | 'fallback'; /** Age of the cached scanner data when `scannerDataSource` is 'cache'. */ readonly scannerDataAgeMs?: number; } /** * nexus-agents/mcp - Fallback Scanner Data * * Embedded snapshot of the vulnerability-scanner-registry manifest. * Used when the live registry fetch fails (network issues, gh CLI * unavailable, etc.). Updated periodically from the canonical * registry at github.com/williamzujkowski/vulnerability-scanner-registry. * * @module mcp/tools/repo-security-plan-fallback * (Source: Consensus vote — externalize scanner registry, 6-0 unanimous) */ /** Embedded scanner data snapshot used when live registry is unavailable. */ declare const FALLBACK_SCANNER_DATA: ScannerData; /** * nexus-agents/mcp - Repository Security Plan Logic * * Generates a language-aware security scanning pipeline recommendation * by composing repo_analyze output with scanner registry data. * Fetches fresh data from vulnerability-scanner-registry GitHub Releases; * falls back to embedded snapshot if fetch fails. * * @module mcp/tools/repo-security-plan * (Source: Issue #1079, externalization vote 6-0 unanimous) */ /** Internal scanner entry used by plan builder. */ interface ScannerEntry { readonly name: string; readonly displayName: string; readonly categories: readonly string[]; readonly license: string; readonly pricingModel: string; readonly supersedes?: readonly string[]; } /** Language mapping: category → scanner names. */ interface LanguageMapping { readonly sast: readonly string[]; readonly sca: readonly string[]; readonly secrets: readonly string[]; } /** Resolved scanner data for plan building. */ interface ScannerData { readonly scanners: readonly ScannerEntry[]; readonly languageMap: Readonly>; /** * Where the scanner data came from (#6037). THREE states, not two: a stale * cache is not a live registry read, and it used to be stamped 'registry' * because the only test was `manifest !== null`. */ readonly source: 'registry' | 'cache' | 'fallback'; /** Age of the cached data when `source` is 'cache'. */ readonly ageMs?: number; } /** Resolve scanner data: fetch from registry, fall back to embedded. */ declare function resolveScannerData(): Promise; /** Options for buildPlanFromAnalysis (allows optional fields for testability). */ interface BuildPlanOptions { readonly repo: string; readonly categories?: readonly string[] | undefined; readonly maxScanners?: number | undefined; } /** Generate a security scanning plan for a repository (fetches live data). */ declare function generateSecurityPlan(input: RepoSecurityPlanInput): Promise; /** Pure function: build plan from analysis + scanner data (testable). */ declare function buildPlanFromAnalysis(analysis: RepoAnalysis, input: BuildPlanOptions, data?: ScannerData): RepoSecurityPlan; /** * nexus-agents/mcp - Scanner Registry Fetcher * * Fetches the scanner-registry.json manifest from the * vulnerability-scanner-registry GitHub Releases at runtime. * Uses a TTL cache and falls back to embedded data on failure. * * @module mcp/tools/scanner-registry-fetcher * (Source: Consensus vote — externalize scanner registry, 6-0 unanimous) */ /** A scanner entry from the registry manifest. */ interface RegistryScanner { readonly name: string; readonly displayName: string; readonly categories: readonly string[]; readonly license: string; readonly pricingModel: string; readonly relationships?: readonly RegistryRelationship[] | undefined; } /** A relationship edge between scanners. */ interface RegistryRelationship { readonly target: string; readonly type: 'uses' | 'supersedes' | 'bundles' | 'competes-with'; } /** Language matrix: category → scanner names. */ interface LanguageMatrixEntry { readonly sast?: readonly string[] | undefined; readonly sca?: readonly string[] | undefined; readonly secrets?: readonly string[] | undefined; readonly container?: readonly string[] | undefined; readonly iac?: readonly string[] | undefined; readonly dast?: readonly string[] | undefined; } /** The full registry manifest shape. */ interface ScannerRegistryManifest { readonly version: string; readonly generatedAt: string; readonly scanners: readonly RegistryScanner[]; readonly languageMatrix: Readonly>; } /** Clear the cache and inflight state (for testing). */ declare function clearRegistryCache(): void; /** * Get the scanner registry, fetching from GitHub if cache is stale. * Returns null if no cached data and fetch fails. */ declare function getRegistryManifest(): Promise; /** * nexus-agents/mcp - Search Codebase MCP Tool * * Keyword search across an indexed codebase symbol table. * Returns matching functions, classes, methods, interfaces, and types * with relevance scoring and file locations. * * @module mcp/tools/search-codebase-tool */ declare const SearchCodebaseInputSchema: z.ZodObject<{ query: z.ZodString; directory: z.ZodOptional; limit: z.ZodOptional; mode: z.ZodOptional>; maxDepth: z.ZodOptional; }, z.core.$strip>; type SearchCodebaseDeps = BaseMcpToolDeps; /** @category MCP */ declare function registerSearchCodebaseTool(server: McpServer, deps: SearchCodebaseDeps): void; /** * nexus-agents/mcp - Extract Symbols MCP Tool * * AST-based symbol extraction for token-efficient code retrieval. * Returns function, class, method, interface, type definitions from * TypeScript/JavaScript files — 80%+ smaller than full file reads. * * @module mcp/tools/extract-symbols-tool */ declare const ExtractSymbolsInputSchema: z.ZodObject<{ filePath: z.ZodString; mode: z.ZodOptional>; maxChars: z.ZodOptional; maxSymbols: z.ZodOptional; }, z.core.$strip>; type ExtractSymbolsDeps = BaseMcpToolDeps; /** @category MCP */ declare function registerExtractSymbolsTool(server: McpServer, deps: ExtractSymbolsDeps): void; /** * nexus-agents/mcp - Search Usages MCP Tool (#4265 / epic #4249 Child A) * * Structural USAGE / call-site search for a symbol, backed by ast-grep * (`@ast-grep/napi`, MIT, Rust + tree-sitter). Answers "where is X used / * called" — the gap `search_codebase` cannot fill: that tool indexes declared * symbol NAMES only (declarations), not usages/call-sites. This tool is * additive and complementary; it does NOT replace the ts-morph symbol * extractor (`indexer/symbol-extractor.ts`), which stays the type-checker-aware * declaration index. * * Syntactic, not type-aware: matches are structural (a `foo()` call, an * `obj.foo()` member call, `new foo()`, an import, a bare reference) and are * NOT resolved against a type checker — a member call on an unrelated object of * the same property name will match. That is the documented ast-grep trade-off * (the epic keeps ts-morph for type-aware needs). * * **Read-only**: reads source files and walks their ASTs; performs NO writes, * so the Rule-of-Two (untrusted-input + write + secrets) is not triggered. * * @module mcp/tools/search-usages-tool */ declare const SearchUsagesInputSchema: z.ZodObject<{ symbol: z.ZodString; path: z.ZodOptional; dir: z.ZodOptional; lang: z.ZodOptional>; limit: z.ZodOptional; maxDepth: z.ZodOptional; }, z.core.$strip>; type SearchUsagesDeps = BaseMcpToolDeps; /** @category MCP */ declare function registerSearchUsagesTool(server: McpServer, deps: SearchUsagesDeps): void; /** * nexus-agents/mcp - Query Trace MCP Tool (Epic #952, Phase 5) * * Read-only MCP tool that queries execution traces from disk * (./runs/{runId}/trace.jsonl) written by TraceWriter. * * @module mcp/tools/query-trace-tool */ declare const QueryTraceInputSchema: z.ZodObject<{ runId: z.ZodString; eventType: z.ZodOptional; limit: z.ZodOptional; }, z.core.$strip>; type QueryTraceInput = z.infer; type QueryTraceDeps = BaseMcpToolDeps; /** @category MCP */ declare function registerQueryTraceTool(server: McpServer, deps: QueryTraceDeps): void; /** * Job-result store for async-mode MCP tools (#3042, Stage 1 of #2631). * * Persists the final result of a background-dispatched MCP tool * invocation to `/jobs/result-.json`. Lets a * caller dispatch a long-running tool via `dispatch: 'async'`, receive a * `jobId` immediately, and poll for the result via `get_job_result` * (or any other reader that imports `readJobResult`). * * **Why a sidecar file (not the structured-task-state log):** Stage 1 * deliberately doesn't extend `StructuredTaskState` — that schema change * is Stage 2 (#3043). Putting the result in a sidecar file lets the * async-mode protocol ship and be validated end-to-end before the schema * migration lands. Once Stage 2 ships, this store can be deprecated: * `query_task_state` will return the result inline and the sidecar files * become legacy that the next cleanup sweep can remove. * * **Why per-repo storage (`jobs` is in `PER_REPO_SUBDIRS`):** a job * dispatched on repo A should not be pollable on repo B. The split * matches `tasks/state-orch-*.jsonl` which is also per-repo. * * Status lifecycle: `pending` → (`complete` | `failed` | `cancelled`). * `cancelled` isn't written by Stage 1 (no `cancel_job` yet — that's * a follow-up under the same Stage 1 umbrella) but the type space * carries it so the next PR doesn't churn the schema. * * @module mcp/jobs/job-result-store */ /** Lifecycle status of a job-result record. */ declare const JobStatusSchema: z.ZodEnum<{ failed: "failed"; cancelled: "cancelled"; pending: "pending"; complete: "complete"; }>; type JobStatus = z.infer; /** * One on-disk job-result record. Versioned so future readers can * tell which Stage wrote it — bump on schema break. */ declare const JobResultSchema: z.ZodObject<{ v: z.ZodLiteral<1>; jobId: z.ZodString; toolName: z.ZodString; status: z.ZodEnum<{ failed: "failed"; cancelled: "cancelled"; pending: "pending"; complete: "complete"; }>; createdAt: z.ZodISODateTime; completedAt: z.ZodOptional; result: z.ZodOptional; error: z.ZodOptional; errorKind: z.ZodOptional>; signalAccepted: z.ZodOptional; producerVersion: z.ZodOptional; lastProgressAt: z.ZodOptional; }, z.core.$strip>; type JobResult = z.infer; /** * List job records under `/jobs/` (#3046 Stage 5). * * Returns ALL records sorted by `createdAt` descending (newest first). * Caller filters by `toolName` / `status` via the `list_jobs` MCP tool — * we don't push the filter logic in here because tools change shape but * the store doesn't. * * **The result payloads are intentionally EXCLUDED** from each summary * — large complete-status records can be 1 MiB each (per Stage 2's * TASK_RESULT_MAX_BYTES cap), and `list_jobs` is meant for discovery, * not retrieval. Callers re-fetch full records via `get_job_result(jobId)`. * * Schema-mismatch + unreadable files are silently dropped (logged as * warnings), same policy as `readJobResult`. */ interface JobSummary { readonly jobId: string; readonly toolName: string; readonly status: JobResult['status']; readonly createdAt: string; readonly completedAt?: string; /** True iff the record carries an error message (status === 'failed'). */ readonly hasError: boolean; /** Last heartbeat from the job body (#6162); absent when none was recorded. */ readonly lastProgressAt?: string; } /** * Task-state job-result source (#3090 / epic #2631 Stage 2 migration). * * Adapts the Stage-2 `StructuredTaskState` surface into the Stage-1 * `JobResult` shape so `get_job_result` (and, later, `list_jobs`) can read * an async job's result from the canonical task-state log instead of the * sidecar. This is the **reader half** of the sidecar→Stage-2 migration: * it is flag-gated with the sidecar as the default, so production behavior * is unchanged until the writer half (#3091) makes `jobId === taskId` real. * * Mapping contract (see #3090): * - status: `cancellation` present → `cancelled`; `stage==='complete'` → * `complete`; `stage==='failed'` → `failed`; else → `pending` * (`blocked` is recoverable, still in-flight). * - `result` ← `state.result`; `error` ← cancellation.reason (cancelled) * or the most-recent blocker (failed). * - `toolName` ← derived from the jobId prefix (`orch-` → `orchestrate`). * - `createdAt` ← `state.createdAt`; `completedAt` ← `state.updatedAt` when * terminal, omitted otherwise. * * @module mcp/jobs/task-state-source */ /** * Which store answered a job-result read. The values are the * `NEXUS_JOB_RESULT_SOURCE` value set (`config/env-schema.ts`) so a caller * can relate the answer to the toggle that selected it. */ type JobResultSource = 'sidecar' | 'task_state'; /** * `get_job_result` MCP tool (#3042, Stage 1 of epic #2631). * * Read-only companion to `orchestrate({ dispatch: 'async' })`: returns the * job-result record written by the background dispatch. Callers poll * until `status !== 'pending'` and then read `result` (on `complete`) * or `error` (on `failed` / `cancelled`). * * Stage 2 (#3043) will migrate the result inline to `StructuredTaskState` * and `query_task_state` will return the same payload; this tool is * the Stage-1 surface that lets async-mode ship before the schema * migration lands. * * @module mcp/tools/get-job-result-tool */ declare const GetJobResultInputSchema: z.ZodObject<{ jobId: z.ZodString; }, z.core.$strip>; type GetJobResultInput = z.infer; /** * Response envelope. `found: false` means the jobId is unknown (or the * sidecar file is unreadable / future-schema). `found: true` carries * the full record — caller branches on `record.status`. */ interface GetJobResultResponse { readonly jobId: string; readonly found: boolean; readonly record?: JobResult; /** * Set when a `pending` record has outlived the runaway guard that bounds * every job body (#4976), so no live process can still be working on it. * * The record itself is left saying `pending` — it is evidence of what was * observed, and rewriting it on read would destroy that. This field is the * qualifier a poller needs to stop waiting. */ readonly abandoned?: boolean; /** * Whether `record.producerVersion` identifies a build (#5008). Present * whenever `found` is true. * * This tool's own `_meta['nexus-agents/build']` stamp names the READER's * build; `record.producerVersion` names the build that ran the job. `false` * when the record predates the field or the producer was a `'dev'` build, * in which case the two stamps must not be compared. */ readonly producerVersionMeasured?: boolean; /** * Which store the record came from (#5008 follow-up). Present whenever * `found` is true. A `task_state` record is synthesized from the task-state * log and never carries `producerVersion`, so on that source an absent * version says nothing about the producer's age or build — only a `sidecar` * record's absence means it predates the field. */ readonly producerVersionSource?: JobResultSource; readonly errorMessage?: string; } type GetJobResultDeps = BaseMcpToolDeps; /** @category MCP */ declare function registerGetJobResultTool(server: McpServer, deps: GetJobResultDeps): void; /** * `list_jobs` MCP tool (#3046 / epic #2631 Stage 5). * * Cross-session discovery surface for async-mode jobs. The Stage-1 * sidecar at `/jobs/result-.json` persists each * job's record across server restarts; `list_jobs` walks the directory * and returns one summary per record (jobId, toolName, status, * timestamps). Result payloads are intentionally excluded — large * `complete` records can be 1 MiB each (per Stage 2's * `TASK_RESULT_MAX_BYTES` cap), and this tool is meant for discovery, * not retrieval. Callers fetch full records via `get_job_result(jobId)`. * * Filters: optional `toolName` (exact match) and `status` * (`pending | complete | failed | cancelled`). Both applied client-side * after the directory walk so the store stays filter-free. * * Sort order: newest `createdAt` first — matches the typical "what just * happened" discovery flow. * * @module mcp/tools/list-jobs-tool */ declare const ListJobsInputSchema: z.ZodObject<{ toolName: z.ZodOptional; status: z.ZodOptional>; limit: z.ZodOptional; }, z.core.$strip>; type ListJobsInput = z.infer; interface ListJobsResponse { readonly count: number; /** * Whether the LIMIT CAP dropped entries. Deliberately narrow: it says nothing * about whether the underlying read was complete, which is what * {@link ListJobsResponse.jobsDirUnreadable} and * {@link ListJobsResponse.unparseableRecords} are for (#6038). */ readonly truncated: boolean; readonly jobs: readonly JobSummary[]; /** Present only when the jobs directory exists but could not be enumerated. */ readonly jobsDirUnreadable?: boolean; /** Present only when sidecar files were found but failed to parse or validate. */ readonly unparseableRecords?: number; } type ListJobsDeps = BaseMcpToolDeps; /** @category MCP */ declare function registerListJobsTool(server: McpServer, deps: ListJobsDeps): void; /** * `cancel_job` MCP tool (#3042 Stage 1b / epic #2631). * * Marks an async-mode job as cancelled. Three semantic outcomes: * * - **`cancelled`** — the job was `pending` and is now `cancelled`. This * writes the durable `cancelled` record, and the terminal writers * (`writeJobComplete`/`writeJobFailed`) no-op against it (#4017/#4022), * so a later-settling background job can no longer silently revert the * cancellation. See the IMPORTANT caveat below on what this does NOT stop. * - **`already_complete`** — the job is already `complete` / `failed`. * The terminal record is preserved (Security flag from #3041 vote: * cancel-after-complete must not rewrite history). * - **`already_cancelled`** — second + cancellation against the same * jobId is a no-op. Idempotent for safe retry. * * **What cancel does to in-flight work (#4086).** Cancelling a `pending` job now * fires that job's `AbortController` (registered by `runAsJob`, threaded into the * job body as an `AbortSignal`). A `runAsJob`-dispatched tool that THREADS the * signal into its awaited operations is genuinely interrupted in this process; * when its `run()` rejects on abort, the terminal writers no-op against the * already-written `cancelled` record (#4022), so the cancellation wins. A tool that * IGNORES the signal still runs to completion (you cannot stop an unyielding * Promise from outside) — but its record stays `cancelled`. So adopting the signal * is per-tool and incremental; the dispatch infrastructure now makes it possible. * (`consensus_vote` had its own AbortSignal plumbing pre-#4086, #3038.) * * Same-process only: it does not abort work in OTHER processes (no IPC; a * per-process AbortController can only abort what it owns). In a multi-process * deployment the durable cancellation record is observable via * `get_job_result` / `list_jobs`, but the worker process must poll for it. * * @module mcp/tools/cancel-job-tool */ declare const CancelJobInputSchema: z.ZodObject<{ jobId: z.ZodString; reason: z.ZodOptional; }, z.core.$strip>; type CancelJobInput = z.infer; /** Outcome envelope. `status` discriminates the four cases. */ interface CancelJobResponse { readonly jobId: string; /** Outcome category — see module docstring. */ readonly outcome: 'cancelled' | 'already_complete' | 'already_cancelled' | 'unknown_job'; /** The terminal status now on disk (after this call). Absent for `unknown_job`. */ readonly status?: JobStatus; /** Human-readable explanation matching the outcome. */ readonly message: string; } type CancelJobDeps = BaseMcpToolDeps; /** @category MCP */ declare function registerCancelJobTool(server: McpServer, deps: CancelJobDeps): void; /** * nexus-agents/audit - Audit Logger Implementation * * Structured audit logger with file rotation and hash chain support. * SIEM-compatible JSON-L output format. * * (Source: Issue #193 - Phase 3 structured audit logging) * * @module audit/audit-logger */ declare class AuditLogger implements IAuditLogger { private readonly storage; private readonly logger; private readonly enableHashChain; private readonly minSeverity; private readonly categories?; private readonly maxQueueDepth; private lastHash; private eventQueue; private flushTimer; private readonly flushIntervalMs; private closed; private inFlightFlush; private droppedEventCount; private persistFailureCount; private readonly onPersistFailure; constructor(config: AuditLogConfig, storage?: IAuditStorage, logger?: ILogger, onPersistFailure?: (error: Error) => void); private startFlushTimer; /** * Fail-loud handler for an audit-persist failure (#3916). A dropped/failed * audit write undermines the tamper-evident hash chain (ADR-0017 / * docs/security/audit-hash-chain-threat-model.md), so unlike the best-effort * cost path this is NOT swallowed: it logs prominently at error level, * increments a process-lifetime counter (exposed via * {@link getPersistFailureCount}), and invokes the optional `onPersistFailure` * hook so a governance consumer can escalate (e.g. raise/alert). Callers on the * awaited flush()/close() path additionally receive the thrown error directly. */ private recordPersistFailure; /** * Process-lifetime count of audit flushes that FAILED to persist (#3916). A * non-zero value means at least one audit event was not durably written — the * hash chain may have a gap. Surfaced so the failure is observable rather than * silent. */ getPersistFailureCount(): number; private shouldLog; private createEvent; log(input: AuditEventInput): void; logToolInvocation(opts: ToolInvocationAuditOpts): void; logPolicyDecision(opts: PolicyDecisionAuditOpts): void; logSecurityEvent(opts: SecurityEventAuditOpts): void; logRateLimitViolation(opts: RateLimitAuditOpts): void; /** * Log an authority-tier transition (Epic D / ADR-0017, #3842). A promotion or * demotion of a loop's authority tier is recorded as a hash-chained * `governance`-category event whose `metadata.tierTransition` carries the * structured {@link TierTransitionPayload} ({subject, fromTier, toTier, * evidenceRef, ratificationVoteRef?}). * * The emitter does NOT itself enforce the ratification invariant (a promotion * with no `ratificationVoteRef` is still chained — tampering with the log to * remove the field must not erase the event). The invariant is enforced by the * ratification gate (`scripts/check-authority-tier-drift.ts`), which reads the * chained events back and FAILS a `promotion` lacking a vote ref. A promotion * is emitted at `warning` severity (it grants authority) so it surfaces above * the default info floor; a demotion is `info` (it is the safe direction). */ logTierTransition(opts: TierTransitionAuditOpts): void; /** * Log that startup has begun (#5577). * * Emitted when the audit logger itself is constructed, which is long before * authentication, tool registration and transport connect have run. The * completion record is `system.startup`, written at the point the server * reaches "waiting for requests" — see `logSystemStartup`. * * `outcome` is `success` because the enum has no in-progress value; the * phase lives in the action name, not the outcome. */ logSystemStartupBegin(metadata?: Record): void; /** * Log the startup COMPLETION record (#5577). * * Must be called only once startup has actually finished. Before #5577 this * was written the moment the audit logger was constructed, so a throw in * authentication, tool registration or transport connect left a durable * "startup succeeded" record for a server that never started. * * @param metadata - Optional structured detail attached to the record. * @param outcome - `success` when the server reached "waiting for requests"; * `failure` when the startup sequence threw. */ logSystemStartup(metadata?: Record, outcome?: 'success' | 'failure'): void; /** * @deprecated Use {@link logSystemShutdownBegin}. Kept so #5577 does not * remove a published method; it now delegates, so the record it writes is * `system.shutdown.begin` rather than the old `system.shutdown` / * `success`, which claimed a shutdown that had not happened. Removal is * tracked for the next major. * @param metadata - Optional structured detail attached to the record. */ logSystemShutdown(metadata?: Record): void; /** * Log that shutdown has begun (#5577). * * There is deliberately no matching completion record. This logger is the * FIRST thing closed in the cleanup handler — the EventBus, observer, * memory, bridge and server are torn down after it — so by the time * shutdown has actually completed the sink is closed and nothing can be * written. The previous `system.shutdown` / `success` record claimed a * completed shutdown that had not happened. * * Known consequence, raised by the panel that chose this shape: a * `system.shutdown.begin` with no successor is indistinguishable from a * hard kill. That cannot be resolved from inside a dying process; recording * the real outcome needs a supervisor outside it. Absence of a completion * record here is by construction, not a lost event. */ logSystemShutdownBegin(metadata?: Record): void; private drainAndFlushOnce; /** * Drain the in-memory queue to storage AND flush the storage's own buffer * to disk. Concurrent calls are coalesced into a single in-flight promise * so an overlapping flush-timer tick cannot spawn parallel drains (see * #2979). A caller arriving while a flush is already running awaits the * existing promise; their newly-queued events, if any, are picked up by * the next flush. */ flush(): Promise; close(): Promise; } declare function createAuditLogger(config: AuditLogConfig, storage?: IAuditStorage, logger?: ILogger, onPersistFailure?: (error: Error) => void): AuditLogger; /** * PR Review Findings — typed verification gate per #2225 + #2233 Child 3 * * The Bench's load-bearing differentiator vs. existing autonomous-coding * frameworks (per the build-vs-buy audit on #2232) is that adversarial * voters MUST apply the 2026-04-25 verification gate before filing a * finding. Without enforcement, voters revert to the 100% false-positive * rate that triggered #2225 in the first place. * * This module provides the typed structures + parser. Voters are * instructed to emit a YAML-fenced `findings` block alongside their free- * form reasoning; we extract structured Findings out of that block and * mark each as verified or unverified based on the gate output. * * Aggregation rule (enforced in pr-review-tool.ts): * request_changes requires at least one VERIFIED finding from a * non-error voter. Unverified findings surface in the response but * don't trigger blocking. * * @module mcp/tools/pr-review-findings */ /** The 4-point verification gate (#2225). Each check is either `passed` * (the voter applied it and cleared) or a non-empty string explaining what * was named (only meaningful for `named_assertion`). Anything else fails. */ interface VerificationGate { /** Re-read cited line + 5 lines before/after. */ readonly reread_cited_line: 'passed' | 'failed' | 'skipped'; /** Traced from a real entry point. */ readonly traced_call_path: 'passed' | 'failed' | 'skipped'; /** Concrete failing assertion named (e.g. "leaked listener", "throws on * null input"). String, not boolean — empty/short = failed. */ readonly named_assertion: string; /** Ruled out language non-issues (JS single-threaded, Map iteration * semantics, etc). */ readonly ruled_out_language_non_issue: 'passed' | 'failed' | 'skipped'; } type FindingSeverity = 'critical' | 'high' | 'medium' | 'low'; interface Finding { /** One-line summary of the issue. */ readonly summary: string; /** path/file.ext:line citation. */ readonly location: string; /** Severity classification. */ readonly severity: FindingSeverity; /** Verification gate output. */ readonly gate: VerificationGate; /** Detailed claim — what's wrong, why it matters. */ readonly claim: string; /** Derived: did all 4 gate checks pass with substance? Computed by * `isFindingVerified`. */ readonly verified: boolean; } /** * nexus-agents/mcp — PR-Review Large-Diff Budget Packer (#4140, epic #4130). * * Option A of the large-diff affordance: when a PR diff exceeds the voter PANEL * budget (since #6003 derived from the panel's context windows in * `pr-review-panel-budget.ts`; the hash cap `MAX_DIFF_LENGTH` is a separate * budget, see `packDiffForPanelAndBinding`), pack it down to a REAL, security-prioritized subset * of WHOLE files instead of hard-failing at the schema or lossily hand-truncating * mid-hunk. A packed review is honestly labeled PARTIAL and (per the #4140 C1 * gate wired in pr-review-tool.ts) is BARRED from a verified-approve — it can * BLOCK on a reviewed file but never verified-APPROVE. * * This module is PURE, deterministic, and I/O-free: no model call, no filesystem, * no clock. It is unit-testable in isolation and reused by `executePrReviewBody`. * * FILE-BOUNDARY SAFETY is the load-bearing invariant. `splitByFile` splits only on * `^diff --git ` file headers, so each unit is a whole file's hunk-set. The packer * includes each file WHOLE or drops it — worst case a single over-budget file is * included TRUNCATED with an explicit marker AND still listed as partially-seen. A * voter never receives a corrupted mid-hunk fragment that reads as complete. * * NOT built here (deferred): the exhaustive multi-pass arm (#4151), file-fetch * (#4152), and any scored/weighted ranker. Ordering is a documented two-tier * partition (sensitive-path files first, stable; then the rest in diff order) — * NOT a score. * * @module mcp/tools/pr-review-diff-budget */ /** * Machine-readable coverage of a large-diff review (#4140). Present ONLY when the * input diff exceeded the panel budget and was packed; ABSENT for a whole-diff * review (a within-budget diff is byte-identical to pre-#4140). `partial: true` * means the verdict was BARRED from a verified-approve (the C1 gate below). * * pr_review itself now reports the {@link PrReviewBindingCoverage} extension * (#6003), which is also present when the panel read everything but the hash * binds only a prefix; this base shape is what the single-budget * {@link packDiffForReview} callers (triangulated review) still get. */ interface PrReviewCoverage { /** Number of files whose full diff the panel actually reviewed. */ readonly reviewedFiles: number; /** Total number of files in the original diff. */ readonly totalFiles: number; /** Paths NOT fully reviewed (dropped, or the one truncated-head file). */ readonly droppedFiles: readonly string[]; /** True when coverage is incomplete (`droppedFiles.length > 0`). */ readonly partial: boolean; /** Day-one strategy is always `'budget'` (exhaustive arm deferred to #4151). */ readonly strategy: 'budget'; } /** Where the panel-read budget came from (#6003). */ type PanelBudgetSource = 'registry' | 'binding-cap-fallback'; /** * Coverage of a pr_review whose panel read and hash binding are decided * SEPARATELY (#6003). Extends {@link PrReviewCoverage}: `partial` keeps its * meaning — the PANEL did not read every file — and is what the C1 gate keys on. * `binding` is a different fact: whether the record's `reviewedDiffHash` covers * every byte or only a prefix. All four combinations are reachable. * * Every byte field is UTF-8 (`Buffer.byteLength(text, 'utf-8')`), the same unit * the hash truncates on — never UTF-16 code units (#5818). */ interface PrReviewBindingCoverage extends PrReviewCoverage { /** `'full'` — the panel was sent the whole diff; `'partial'` — a packed subset. */ readonly panelRead: 'full' | 'partial'; /** `'full'` — the hash covers every byte; `'prefix'` — only the first `boundBytes`. */ readonly binding: 'full' | 'prefix'; /** * Which bytes `binding` / `boundBytes` were measured over (#6177): the RAW * input the hash covers, the diff as handed (no sanitizer in the path), or * the SANITIZED text as a stated fallback. See {@link BindingMeasurementSource}. */ readonly bindingSource: BindingMeasurementSource; /** UTF-8 bytes of the diff text the panel actually read (`packedDiff`). */ readonly reviewedBytes: number; /** * UTF-8 bytes the hash binds: `min(, bindingCapBytes)`. * Measured over the {@link BindingMeasurement}, NOT over `totalBytes` — on the * MCP path the two differ by whatever the sanitizer stripped (#6177). */ readonly boundBytes: number; /** * UTF-8 bytes of the diff the packer was handed — the panel-read * denominator. On the MCP path this is the SANITIZED text; the binding side * is measured separately (see `bindingSource`). */ readonly totalBytes: number; /** Where the panel-read budget came from. */ readonly budgetSource: PanelBudgetSource; /** The budget derivation or the fallback reason, verbatim from {@link ReviewBudgets.detail}. */ readonly budgetDetail: string; } /** * Where the bytes the BINDING is measured over came from (#6177): * - `'raw'` — the middleware's pre-sanitization measurement, taken beside the * raw hash. The bytes `reviewedDiffHash` actually covers. * - `'input'` — no sanitizer in the path (the local-ledger door), so the diff * as handed IS the raw diff and the hash was computed over it. * - `'sanitized-fallback'` — a sanitizer ran but supplied no raw byte length * (an older middleware). Measured over the sanitized text and SAID SO: this * source can under-state a prefix binding, so a consumer must not read its * `full` as a raw measurement. */ type BindingMeasurementSource = 'raw' | 'input' | 'sanitized-fallback'; /** * nexus-agents/mcp — PR-Review Audit-Record Producer (#4031). * * The pr_review side of the #3831 Option-C arc: turn a completed review into an * authentic, self-hashed governance record bound to {prNumber, baseSha, * reviewedDiffHash, verdict}, so the warn-first governor-review gate can find a * diff-bound record for the PR it is checking. Split out of pr-review-tool.ts to * keep that file's single-purpose review flow lean. * * Best-effort and never-throws: a missing binding or a write failure is surfaced * as a structured {@link PrReviewRecordOutcome}, never an exception into the * review path (an audit sink must not break the operation it observes). * * @module mcp/tools/pr-review-record-producer */ /** * Structured outcome of the best-effort Option-C audit-record persistence * (#4031). Surfaced on the pr_review response so an MCP caller can SEE whether a * record was written and, when not, WHY — mirroring the consensus_vote * `voteRecordPersisted` observability. Reasons: * - `binding-inputs-absent` — `prNumber` and/or `baseSha` were not supplied, so * there is nothing to bind the record to (the warn-first skip; not an error). * - `simulated` — the review used simulated voters; a committed record would * seed governance from non-live output (mirrors #2319 for votes). * - `no-live-votes` — every voter errored, so the aggregate verdict was produced * by NO live opinion. Persisting would write a gate-satisfying record for a * review that never actually happened (the governor-review analogue of the * consensus_vote `no_quorum` void, #4053). Skipped so a failed review cannot * silently flip the #3831 gate from warn to a false pass. * - `raw-hash-absent` — a sanitizer WAS in the path but supplied no * pre-sanitization hash, so the only binding available is over sanitized * bytes the gate can never reproduce from git. Refused rather than written: * the record would carry a binding that cannot match plus a disclosure * asserting the sanitizer left those bytes alone (#5385, panel condition). * - `write-failed` — the binding was present but the ledger path was unresolved * or the append failed (the producer already logged the underlying cause). */ type PrReviewRecordOutcome = { readonly persisted: true; readonly prNumber: number; readonly baseSha: string; readonly reviewedDiffHash: string; readonly sequence: number; } | { readonly persisted: false; readonly reason: 'binding-inputs-absent' | 'simulated' | 'no-live-votes' | 'diff-not-unified' | 'raw-hash-absent' | 'write-failed'; readonly detail: string; }; /** * Proposal construction for `pr_review`. * * Extracted from `pr-review-tool.ts` (#5385), which sat at 398 of its 400-line * budget — threading the sanitization disclosure through pushed it over, and * this is the cohesive piece to move, because the builder IS the sanitization * concern. A pure move apart from the `removedBeforeThisCall` parameter that * issue adds. * * `pr-review-tool.ts` re-exports the symbol, so both barrels * (`mcp/index.ts`, `mcp/tools/index.ts`), the published `exports/mcp.ts`, and * `scripts/pr-review-local.ts` / `scripts/pr-review-eval-run.ts` keep importing * it unchanged. The `PrReviewInput` import is type-only and therefore erased, * so the re-export creates no runtime cycle. * * @module mcp/tools/pr-review-proposal */ /** Builds the proposal text passed to voters. The voters are designed for * yes/no proposals — by framing the diff as "should this PR be merged?" we * get usable output without needing new system prompts (Child 3 will add * those). * * **Sanitization lives HERE, not at the tool boundary (#5258 item B).** The * `securityTier: 'external'` declared on the registered tool only protects the * MCP path, because the middleware is constructed inside `registerPrReviewTool`. * Three other callers reach the voters without it — `.github/workflows/ * pr-review.yml`, `scripts/pr-review-local.ts` (the documented default path) * and `scripts/pr-review-eval-run.ts` — each importing this builder directly * from `dist/index.js`. On those paths a hostile PR body reached five voters * unfenced, next to the words "should it be merged as-is?". * * This function is the one chokepoint all four callers pass through, so the * protection is attached to the data rather than to one entry point. The MCP * tier check still runs earlier and still refuses; this is the floor beneath * it, and it strips rather than refuses so the script paths degrade instead of * failing shut. Double-sanitizing on the MCP path is idempotent and harmless. */ declare function buildPrReviewProposal(input: Pick, /** * What an EARLIER sanitization stage already removed (#5385). Both counts are * needed because the sanitizer strips two different things through two * different counters — comments alone cannot represent a tag strip, and a note * that says "nothing was removed" about a stripped injection tag is worse than * no note. Defaults to zeroes for the CI and script paths, where nothing runs * before this call. */ removedBefore?: { comments: number; fields: number; tags: number; }): string; /** Voter panel for PR review. PM and AI/ML excluded — they're proposal-level * roles, not code-level. The 5 here are the ones with concrete claims about * code (#2233). */ declare const PR_REVIEW_ROLES: readonly VoterRole[]; /** The BINDING cap, mirrored: the UTF-8 byte cap the canonical `reviewedDiffHash` * binds to (`MAX_REVIEWED_DIFF_BYTES`, #3831). Since #6003 this is NOT the panel * budget: what the 5-voter panel reads is bounded by the voters' context windows * (`pr-review-panel-budget.ts`), and this cap is only the panel budget when that * derivation fails closed. A diff over this cap is never rejected; the record * states that the hash binds a prefix. Still the local-ledger script's diff cap. */ declare const MAX_DIFF_LENGTH = 50000; declare const PrReviewInputSchema: z.ZodObject<{ dispatch: z.ZodDefault; mode: RejectedModeKey; prTitle: z.ZodString; prDescription: z.ZodOptional; prDiff: z.ZodString; repoContext: z.ZodOptional; baseRef: z.ZodOptional; headRef: z.ZodOptional; prNumber: z.ZodOptional; baseSha: z.ZodOptional; repoPath: z.ZodOptional; simulate: z.ZodDefault; errorPolicy: z.ZodDefault>; project: z.ZodOptional; }, z.core.$strip>; type PrReviewInput = z.infer; type PrReviewDecision = 'approve' | 'request_changes' | 'abstain'; interface PrReviewVote { readonly role: VoterRole; readonly decision: PrReviewDecision; readonly confidence: number; /** Free-form reasoning from the voter — full text including the * findings YAML block (which is also parsed into `findings` below). */ readonly reasoning: string; /** Structured findings parsed from the voter's reasoning per #2225 + * #2233 Child 3. Each Finding has a verification gate output and a * derived `verified` boolean. Only verified findings can trigger * request_changes — see aggregatePrDecisions. */ readonly findings: readonly Finding[]; /** Derived from the canonical union so a new seat kind (#6094) cannot be dropped here. */ readonly source: AgentVoteResult['source']; readonly cli?: string | undefined; readonly processingTimeMs: number; readonly errorMessage?: string; } /** Aggregate decision shape (#2250 Child 7). When `summary` is * `request_changes`, `verified` distinguishes high-confidence * blockers (≥1 verified finding) from majority-dissent soft blocks * (≥3/5 voters request_changes without producing verified findings). * Reviewers should apply the verification gate themselves on * unverified soft blocks. */ interface PrReviewAggregate { readonly decision: PrReviewDecision; readonly verified: boolean; /** * #4132: set when `absolute_quorum` DEGRADED a would-be verified approve to a * recoverable `{ decision: 'abstain', verified: false }` because a voter (esp. * the contrarian) errored or the panel was incomplete. `PrReviewAggregate` has * no `no_quorum` state, so `abstain`+`verified:false`+`reason` represents it — * the actionable "re-run the missing voice" signal. Absent on ungated verdicts. */ readonly reason?: string; } interface PrReviewResponse { readonly summary: PrReviewDecision; /** True when the request_changes / approve outcome was driven by * verified findings or unanimous approval; false when the outcome * is a soft signal (majority dissent without verified findings). */ readonly verified: boolean; readonly approveCount: number; readonly requestChangesCount: number; readonly abstainCount: number; readonly errorCount: number; /** Seats that could not read the diff (#6094). Always present; not inside `abstainCount`. */ readonly unverifiableCount: number; readonly reviews: readonly PrReviewVote[]; readonly totalDurationMs: number; /** * The project the panel judged and how the name was decided (#6123): the * caller's `project` input, else derived from the server's working * directory, else `nexus-agents`. Always present. */ readonly project: ResolvedVoterProject; /** * Per-decision cost rollup (#3855): per-voter / per-model token + USD totals * for this governed review. Rides the existing response — no new MCP tool. * Totals are a floor when `costSummary.unmeasuredVoters > 0` (voters whose * adapter reported no usage are counted as unmeasured, not a measured $0). */ readonly costSummary?: DecisionCostSummary; /** * Option-C audit-record persistence outcome (#4031). Present on every * response: `persisted: true` with the record's binding + sequence when an * authentic record was written, otherwise `persisted: false` with the reason. */ readonly recordOutcome?: PrReviewRecordOutcome; /** * Large-diff review coverage (#4140, #6003). Present when the panel read a * packed subset (`panelRead: 'partial'`) OR the audit hash binds only a prefix * of the diff (`binding: 'prefix'`); absent when both are full. Byte fields * are UTF-8. */ readonly coverage?: PrReviewBindingCoverage; } interface PrReviewDeps extends BaseMcpToolDeps { /** * In-process gateway model adapters (#4040) — routes the review panel through * the gateway (HTTP, in-process) instead of a CLI subprocess when configured. * Omitted ⇒ CLI voter path. */ gatewayAdapters?: readonly IModelAdapter[] | undefined; } /** Maps a voter's approve/reject/abstain to PR review semantics. */ declare function mapVoteDecisionToPrDecision(voteDecision: 'approve' | 'reject' | 'abstain'): PrReviewDecision; /** Aggregates per-voter decisions into a single summary outcome with a * verified/unverified tag (#2250 Child 7). * * Tiers, in order: * * 1. **Verified blocker** (`request_changes`, verified=true) — at least * one non-error voter declared `request_changes` AND has at least one * VERIFIED finding (all 4 gate checks passed with substantive * named_assertion). This is the #2225 verification gate. * 2. **Soft blocker** (`request_changes`, verified=false) — ≥3 of 5 * non-error voters voted `request_changes`, but none produced a * verified finding. The retest in #2241 showed voters reliably * flag diff-readable bugs at this rate even without producing the * YAML structure (#2245 covers why). Tagged unverified so reviewers * apply the verification gate themselves. * 3. **Approve** (verified=true) — all non-error voters approve. * 4. **Abstain** (verified=true) — anything else; conservative default. * * Why no "AND has any finding" guard on the soft path: the empirical * data in `pr-review-experiment-results-v2.md` showed voters voting * request_changes but emitting 0 findings (verified or otherwise). * Adding the finding requirement would zero this path out and reproduce * the baseline behavior. */ declare function aggregatePrDecisions(reviews: readonly PrReviewVote[], errorPolicy?: 'standard' | 'absolute_quorum'): PrReviewAggregate; /** @category MCP */ declare function registerPrReviewTool(server: McpServer, deps: PrReviewDeps): void; /** * nexus-agents/mcp - Tools * * MCP tool implementations for the Nexus Agents server. * * (Source: MCP Protocol 2025-11-25) */ /** * Options for tool registration. */ interface ToolRegistrationOptions { /** Logger instance for tool operations */ readonly logger?: ILogger; /** Rate limiter for tool calls */ readonly rateLimiter?: RateLimiter$1; } /** * Result of tool registration. */ interface ToolRegistrationResult { /** Names of registered tools */ readonly tools: readonly string[]; /** Logger used for tool operations */ readonly logger: ILogger; /** Rate limiter used for tool calls */ readonly rateLimiter: RateLimiter$1; } declare function registerTools(_server: McpServer, options?: ToolRegistrationOptions): ToolRegistrationResult; /** * nexus-agents/cli-adapters - Capacity Tracker * * Usage-based capacity tracking for CLI adapters. * Tracks cumulative token/request usage to estimate remaining capacity. * * Since CLI subprocess execution doesn't expose HTTP rate limit headers, * this tracker estimates capacity based on usage patterns. * * @see Issue #456 - Real API rate limit tracking */ /** * Configuration for capacity tracker. */ interface CapacityTrackerConfig { /** Maximum tokens per window */ readonly tokenLimit: number; /** Maximum requests per window */ readonly requestLimit: number; /** Window duration in milliseconds */ readonly windowMs: number; } /** * Capacity tracker for CLI adapters. * * Tracks cumulative usage within a sliding window to estimate * remaining capacity when HTTP headers are not available. * * @example * ```typescript * const tracker = new CapacityTracker(getDefaultConfig('claude')); * * // Record usage after each request * tracker.recordUsage({ inputTokens: 1000, outputTokens: 500 }); * * // Get current capacity status * const status = tracker.getCapacity(); * if (status.rateLimited) { * // Wait before next request * } * ``` */ declare class CapacityTracker { private readonly config; private readonly usageHistory; private requestCount; private windowStart; /** * Timestamps of every recorded request (#3026 finding 4). * * Pre-fix, `requestCount` was a plain counter reset only by the * tumbling-window branch of `pruneOldEntries`. Under continuous * traffic across a window boundary, that branch drops requests that * are still inside the *sliding* window — e.g. with windowMs=60s, a * request at t=59s followed by one at t=61s would tumbling-reset * the counter to 1 even though the t=59s request is still inside * the [1s, 61s] window. The downstream `remainingRequests === 0` * exhaustion check fired prematurely (or too late) depending on * burst patterns. * * Counting via a per-request timestamp array that's pruned the same * way as `usageHistory` keeps the two views consistent. Every * `recordUsage` pushes here; `requestCount` is derived from * `.length` after pruning. */ private requestTimestamps; /** * Whether this process has recorded even one request against this adapter * (#4374). Sticky: pruning the usage window back to empty does NOT clear it, * because the process has still seen the adapter work — it simply has no * recent samples. Without this flag a never-used tracker is indistinguishable * from an idle healthy one, and both report full remaining capacity. */ private hasObserved; /** * Provider-asserted quota exhaustion (#4456), with the horizon the provider * gave. Null until a provider says so — never inferred from local counting. */ private quotaExhaustedUntil; constructor(config: CapacityTrackerConfig); /** * Records token usage from a completed request. */ recordUsage(usage: TokenUsage$1 | undefined): void; /** * Gets current capacity status based on tracked usage. */ getCapacity(): CapacityStatus; /** * Record a PROVIDER's assertion that durable quota is exhausted (#4456). * * Only a `retryAfterMs` longer than the local window counts. A shorter one * is an ordinary per-minute throttle, which {@link CapacityStatus.rateLimited} * already covers — treating it as quota exhaustion would empty the candidate * pool for a condition that clears in under a minute, the failure mode that * kept #4373's enforcement stage switched off. * * Without a `retryAfterMs` the provider gave no horizon, so nothing is * asserted: an exhaustion with no end is not distinguishable here from a * transient error, and inventing a horizon would manufacture a measurement. * * @param retryAfterMs - The provider's stated wait, from `retry-after`. * @returns true when the assertion was durable enough to record. */ recordProviderQuotaExhaustion(retryAfterMs: number | undefined): boolean; /** * Gets time until the rate limit window resets. */ getTimeUntilReset(): number; /** * Resets all tracked usage (for testing or manual reset). */ reset(): void; /** * Updates configuration (e.g., after receiving actual rate limit info). */ updateConfig(partial: Partial): void; /** * Gets current configuration. */ getConfig(): Readonly; /** * Removes entries older than the window duration. */ private pruneOldEntries; } /** * nexus-agents/cli-adapters - Base Adapter * * Abstract base class for CLI adapters with common functionality. * Provides version checking, health checks, and error handling. * * SubprocessCliAdapter extracted to subprocess-adapter.ts per Issue #272. * * (Source: cli-project_plan.md v2.1.0) */ /** * Abstract base class for CLI adapters. * Provides common functionality for version checking, health, and error handling. */ declare abstract class BaseCliAdapter implements ICliAdapter { abstract readonly name: CliName; abstract readonly transport: CliTransport; /** * The executable this adapter actually runs. * * Defaults to {@link name} because for most arms the routing identity and the * binary are the same word. They are NOT always the same: the `gemini` arm * runs `agy` (Antigravity) after Google retired the standalone gemini CLI * (#4346). Conflating the two is how that arm ended up executing `agy` for * work while shelling `gemini --version` for its health check — reporting the * dead binary's version against the live one's floor, and failing its own * availability gate while working perfectly. */ get binaryName(): string; protected readonly logger: ILogger; protected capacityTracker: CapacityTracker | null; protected initialized: boolean; protected cachedVersion?: string; /** * Epoch ms at which {@link cachedVersion} was read off the binary. * * The cache never expires, so this is what lets `healthCheck` say whether * its `reachable` rests on a probe that just ran or on one from minutes ago * (#5864). */ protected cachedVersionAt?: number; constructor(logger?: ILogger); /** * Initializes the capacity tracker. * Called by subclasses after name is set. */ protected initCapacityTracker(): void; /** * Gets the capability profile for this CLI. */ get capabilities(): CapabilityProfile$1; /** * Abstract method for executing a task. * Implemented by concrete adapters. */ abstract executeTask(task: CliTask, options: ResolvedExecutionOptions): Promise>; /** * Abstract method for getting model info. * Implemented by concrete adapters. */ abstract getModelInfo(): ModelInfo; /** * Abstract method for initialization. * Implemented by concrete adapters. */ abstract initialize(): Promise; /** * Abstract method for cleanup. * Implemented by concrete adapters. */ abstract dispose(): Promise; /** * Executes a task with error handling and retries. * * Timeout priority (highest to lowest): * 1. options.timeoutMs - explicit execution option * 2. task.timeoutMs - task-level setting * 3. getTimeoutForTaskAuto() - computed from task complexity and CLI */ execute(task: CliTask, options?: ExecutionOptions$1): Promise>; /** * Computes effective timeout for a task. */ private computeTimeout; /** * Whether the shared outer retry loop ({@link executeCliRetryLoop}) is * allowed to retry this adapter's failures. The base adapter honors the * caller's `allowRetry`. Subprocess adapters override this to suppress * the outer loop when their own transient-retry layer is active, so the * two layers do not nest into multiplied spawns (#2824). */ protected shouldOuterRetry(opts: ResolvedExecutionOptions): boolean; /** * Executes task with retry logic via shared retry loop. */ private executeWithRetry; /** * Feed a provider's own rate-limit assertion into capacity tracking (#4456). * * A `retry-after` the provider stated is far stronger evidence than local * counting: the tracker otherwise sees only this process's spend and cannot * observe a plan quota burned gradually or burned elsewhere, which is the * incident #4351 reported. Only RATE_LIMITED carries that assertion; the * tracker itself decides whether the stated wait is long enough to mean * durable quota rather than a per-minute throttle. */ protected recordQuotaSignal(error: CliError): void; /** * Performs a health check. */ healthCheck(): Promise; /** * Gets CLI version. */ getVersion(): Promise; /** * Gets current capacity status based on tracked usage. * Uses usage-based tracking since CLI subprocess execution * doesn't expose HTTP rate limit headers. * * @see Issue #456 - Real API rate limit tracking */ getCapacity(): Promise; /** * Records usage from a response for capacity tracking. */ protected recordUsage(response: CliResponse): void; /** * Parses version from CLI output. */ protected parseVersion(output: string): string; /** * Checks version compatibility. */ protected checkVersionCompatibility(version: string): VersionStatus; /** * Gets version status message. */ protected getVersionMessage(status: VersionStatus, version: string): string | undefined; /** * Creates a CLI error. */ protected createError(code: CliErrorCode, message: string, cause?: Error): CliError; /** * Normalizes CLI response to common format. */ protected normalizeResponse(text: string, usage?: TokenUsage$1, extra?: Partial): CliResponse; /** * Delays for the specified milliseconds. */ protected delay(ms: number): Promise; } /** * nexus-agents/cli-adapters - Unified CLI Retry Loop * * CLI-specific retry loop used by all CLI adapters (base + Gemini). * Supports optional circuit-breaker integration, returns CliResponse * with retryCount, and maps to FailureCategory for breaker tracking. * * Sibling implementation (see #2230): adapters/retry.ts holds the * generic, type-parameterized `withRetry` for non-CLI use. Don't * reach for that one when you need circuit-breaker coupling; don't * reach for this one from non-CLI code. Math primitives differ * deliberately: * - this file: 1-indexed attempt, +0..30% jitter, cap-after * - adapters/retry.ts: 0-indexed attempt, ±jitterFactor, cap-before-jitter * * If you find yourself writing a third retry loop: stop, run * `consensus_vote` with scope_steward in the panel, and pick whichever * of these two fits — don't add a third. * * (Source: Issue #1596 — Extract shared prompt utils and rate-limit patterns) */ interface CliRetryLoopConfig { readonly maxRetries: number; readonly allowRetry: boolean; readonly baseDelayMs: number; readonly maxDelayMs: number; readonly circuitBreaker?: ICircuitBreaker | null; readonly cli: CliName; readonly logger: ILogger; } interface CliRetryResult { readonly response: CliResponse; readonly retryCount: number; } /** * Calculates exponential backoff delay with jitter. * * @param attempt - Current attempt number (1-indexed) * @param baseDelayMs - Base delay in milliseconds * @param maxDelayMs - Maximum delay cap in milliseconds * @returns Delay in milliseconds with jitter applied */ declare function calculateBackoffDelay(attempt: number, baseDelayMs: number, maxDelayMs: number): number; /** Determines if an error code is retryable. */ declare function isRetryableError(code: CliErrorCode): boolean; /** * Categorizes a CLI error for circuit breaker tracking. * Returns a FailureCategory compatible with the circuit breaker. */ declare function categorizeError(error: CliError): FailureCategory; /** * Executes a CLI operation with retry logic and optional circuit breaker. * * Used by both BaseCliAdapter (no circuit breaker) and GeminiCliAdapter * (with circuit breaker) to eliminate duplicate retry implementations. */ declare function executeCliRetryLoop(executeFn: () => Promise>, config: CliRetryLoopConfig): Promise>; /** * nexus-agents/cli-adapters - Subprocess Adapter * * Base class for subprocess-based CLI adapters. * Used by ClaudeCliAdapter and GeminiCliAdapter. * * Extracted from base-adapter.ts per Issue #272 (file size limits). */ /** * Command configuration returned by getCommand. */ interface CommandConfig { command: string; args: string[]; /** Optional stdin content (prompt passed via stdin instead of args) */ stdin?: string; /** * Optional cleanup callback invoked after the subprocess resolves * (success, error, or timeout). Used by adapters that materialize * temp files for the subprocess (e.g. codex `model_instructions_file`). * Errors thrown by cleanup are logged but do not affect the request result. */ cleanup?: () => void | Promise; } /** * Configuration for transient-error retry behaviour. */ interface TransientRetryConfig { /** Whether transient-error retry is enabled (default: false). */ enabled: boolean; } /** * Base class for subprocess-based CLI adapters. * Used by ClaudeCliAdapter and GeminiCliAdapter. */ declare abstract class SubprocessCliAdapter extends BaseCliAdapter { readonly transport: CliTransport; protected abstract readonly parser: ICliResponseParser; /** Transient-error retry config. Override in subclass to enable. */ protected readonly transientRetry: TransientRetryConfig; /** * The inner {@link retryTransient} layer is the single retry authority * for subprocess CLIs. When it is enabled (the default), the shared * outer retry loop must not also retry: nesting both meant up to 6 * subprocess spawns and ~10-minute hangs on a persistent TIMEOUT, since * the inner layer's timeout extension compounds on every outer attempt * (#2824). The outer loop still runs once, so circuit-breaker failure * recording is unaffected. */ protected shouldOuterRetry(opts: ResolvedExecutionOptions): boolean; /** * Gets CLI command and arguments for execution. * If stdin is provided, it will be written to the process stdin. */ protected abstract getCommand(task: CliTask): CommandConfig; /** * Invokes the optional cleanup hook supplied by getCommand(). Sync * throws are swallowed (warn-only) and async rejections are caught * so cleanup failures never bubble up and mask the real subprocess * result. */ private runSubprocessCleanup; /** * #3026 finding 2: SIGTERM the child when the caller's AbortSignal * aborts mid-execution. Listener auto-detaches on `'close'` so we * don't leak across child lifetimes. */ private attachAbortSignal; /** * Executes a task via subprocess, with optional transient-error retry. * When `transientRetry.enabled` is true, transient errors (timeout, * rate_limit, connection, parse) are retried with exponential backoff * (500ms, 1000ms). Parse errors get max 1 retry (#1533); others get 2. */ executeTask(task: CliTask, options: ResolvedExecutionOptions): Promise>; /** * Retries a transient error with bounded exponential backoff. */ private retryTransient; /** * Spawns a single subprocess execution (no retry). * * `requestId` (#2963 site 3) correlates the timing-breakdown log emitted * on subprocess close back to the parent `executeTask` invocation — * essential when multiple subprocesses for the same CLI run concurrently * (pipelines, votes) and the JSDoc's stated goal ("group by cli + provider * + model and surface tail-latency outliers") requires a way to * disambiguate which timing row belongs to which call. */ /** * Wraps a command's cleanup in a once-guard (#4488). * * `CommandConfig.cleanup` removes a tempdir the command builder created (e.g. * codex's `nexus-codex-sysprompt-*` holding the system prompt). It must run on * EVERY exit path — a path that skips it leaks a directory per invocation, the * leak codex-adapter's own comment records as having exhausted inodes on * long-running MCP daemons — and exactly ONCE, since a second rm could hit a * path the OS has already handed to someone else. */ /** * Result for a synchronous spawn failure (#4488). * * `spawn()` throws synchronously on some failures (EACCES, and ENOENT on * certain platforms), and handler setup can throw too. Those paths never * reach `resolve`, so without catching them the tempdir leaks AND the promise * rejects instead of returning a Result — breaking the never-throws contract * this adapter is supposed to honour. */ private spawnFailure; private onceCleanup; private spawnSubprocess; /** * Sets up child process event handlers for output collection and error handling. */ private setupChildProcessHandlers; /** * Schedules the SIGTERM-on-timeout + SIGKILL-on-grace escalation * (#3026 finding 1). * * The primary timer fires SIGTERM and resolves the caller's promise * immediately so it doesn't wait on a hung child. The escalation * timer (`SIGKILL_GRACE_MS` later) checks whether the child actually * exited and force-reaps it with SIGKILL if not — preventing * zombie accumulation when a child ignores SIGTERM (Node CLIs that * install graceful-shutdown handlers can hang on a broken stream). * Both timers are cleared from the `'close'` handler so a child * that exits within the grace window doesn't see the second signal. */ private scheduleTimeoutWithSigkillEscalation; /** Attach stdout/stderr data handlers + capture first-byte time (#2472). */ private attachStdoutHandlers; /** * Log spawn-latency vs streaming breakdown at info level (#2472). Emits * one structured event per subprocess invocation, queryable via the * existing trace JSONL infrastructure. The breakdown lets operators * identify whether a slow run was caused by: * - High spawn-latency: model gateway took its time before producing * the first token (cold-start, queueing, network jitter). * - High streaming-time: response body was large or generation slow. * - Total approaches the timeout cap with no first-byte: hung process. * * Structured fields chosen so existing query_trace tooling can group by * cli + provider + model and surface tail-latency outliers. */ private logTimingBreakdown; /** Classify a subprocess close event into a Result. */ private classifyCloseResult; /** * Handles successful subprocess output. */ protected handleSubprocessOutput(stdout: string, stderr: string, startTime: number): Result; /** * The parser found no usable content. An error-only stream (e.g. OpenCode * NDJSON `{"type":"error"}`) surfaced an `errorMessage`: classify it before * the generic PARSE_ERROR path, which would mask the real cause. */ private handleNoAnswer; /** * #6269: a well-formed envelope carrying NO answer while stderr names a * credential failure is that failure, not a completion. `agy` exits 0 with * `{"status":"SUCCESS","response":""}` and "Error authenticating: …" on * stderr; handing "" downstream had the vote path parse it (and retry the * parse) for the whole panel budget. Returns `null` — no reclassification — * for a non-empty answer, and for an empty answer with stderr that names no * auth failure: empty stderr is NOT evidence, so that case still flows * through as the empty answer it is. */ private classifyEmptyAnswer; /** * Classify an error-only stream — one where the parser surfaced an * `errorMessage` but no usable content (so `extractResponse` returned null). * Returns a typed error (NOT_AUTHENTICATED / RATE_LIMITED with a remediation * hint, or EXECUTION_ERROR) so an upstream 401 / 429 isn't masked as * PARSE_ERROR. Returns `null` when the parser exposes no error message (no * `extractErrorMessage`, or empty) — the caller then falls back to the * generic unparseable-output recovery. */ private classifyErrorOnlyStream; /** * Handles the parse-failure branch: when the CLI's structured response * parser returned null. Order of recovery attempts (most-specific first): * 1. Rate-limit text in raw stdout (#1320) * 2. Structured CLI error envelope (#2440) * 3. Plaintext fallback for natural-language output (#1401) * 4. Generic PARSE_ERROR with truncated snippet */ private handleUnparseableOutput; /** * Handles subprocess execution errors. */ private handleSubprocessError; /** * Initializes the adapter and capacity tracker. */ initialize(): Promise; /** * Disposes the adapter (no-op for subprocess). */ dispose(): Promise; } /** * nexus-agents/cli-adapters - Claude CLI Adapter * * Subprocess-based adapter for Claude CLI. * Uses JSON output format for stable parsing. * * (Source: cli-project_plan.md v2.1.0) * (Source: docs/research/cli-integration-architecture.md) */ /** * Claude CLI adapter using subprocess transport. * Executes: claude -p --output-format json "" */ declare class ClaudeCliAdapter extends SubprocessCliAdapter { readonly name: CliName; protected readonly parser: ICliResponseParser; private readonly model; constructor(options?: BaseAdapterOptions); /** * Key-free model enumeration (#3405): the claude CLI has no list-models * command and its OAuth token can't call /v1/models, so we enumerate the * vendor's models from the models.dev snapshot. Existence only. */ listModels(): Promise; /** * Gets Claude model information. * `buildModelInfo` matches `cliModelName`, `cliAlias`, and `aliases[]` — * a single call handles 'opus', 'sonnet', 'haiku', current model names, * and the legacy `claude-opus-4` / `claude-haiku-3` / etc. entries that * live in the registry's aliases since #2200 Child 1. * * Truly unrecognized models fall through to conservative defaults * (current Opus pricing). */ getModelInfo(): ModelInfo; /** * Run the task, and on an out-of-credits envelope for the requested model * retry ONCE with the next claude alias the registry lists (#6120). * * The credit exhaustion the claude CLI reports is per MODEL — `fable` * answered "You're out of usage credits" while `sonnet` answered the same * prompt — so it is not evidence against the CLI, and it must not reach the * per-CLI circuit breaker as one. The breaker records what leaves this * method: a substituted success records nothing, and a second capacity * error propagates as the typed error and counts once, because by then the * family, not one model, has failed. A non-capacity `is_error` (auth, a * server error) is returned as-is; another model would not fix it. * * The substitution is stamped on the response as `fallbackFrom` so a vote * record can say which model actually answered (#6115). */ executeTask(task: CliTask, options: ResolvedExecutionOptions): Promise>; /** Appends optional string-type task options to CLI args. */ private appendTaskOptions; /** * Gets CLI command and arguments for execution. * Uses stdin for the prompt to avoid argument escaping issues, * especially important when using --add-dir. */ protected getCommand(task: CliTask): CommandConfig; } /** * CLI Timeout Profiles - Configurable timeouts per CLI tool. * * Delegates to `config/timeouts.ts` (canonical source, Issue #984). * This file provides backward-compatible re-exports. * * @module cli-adapters/cli-timeout-profiles * (Source: Issue #357, CLI delegation testing 2026-01-18) */ /** Per-CLI timeout profiles. Canonical source: `config/timeouts.ts`. */ declare const CLI_TIMEOUT_PROFILES: Record; /** Default timeout profile. Canonical source: `config/timeouts.ts`. */ declare const DEFAULT_TIMEOUT_PROFILE: TimeoutProfile; /** Get timeout for a task. Canonical source: `config/timeouts.ts`. */ declare function getTimeoutForTask(cli: string, complexity: TaskComplexity): number; /** Estimate task complexity from description. Canonical: `cli-timeout-helpers.ts`. */ declare function estimateTaskComplexity(taskDescription: string): TaskComplexity; /** * Get timeout with automatic complexity estimation. * Uses adaptive timeout from outcome history when sufficient data exists (#1534). */ declare function getTimeoutForTaskAuto(cli: string, taskDescription: string): number; /** * nexus-agents/cli-adapters - Gemini CLI Adapter * * Subprocess-based adapter for Gemini CLI with: * - Tiered timeout profiles based on task complexity * - Resilient JSON parsing with fallback strategies * - Exponential backoff retry logic * - Circuit breaker integration for sustained failures * * (Source: cli-project_plan.md v2.1.0) * (Source: Issue #366 - Gemini CLI timeout and parser improvements) * (Source: Issue #389 - Merged enhanced adapter back to canonical) */ /** Configuration for Gemini adapter. Extends BaseAdapterOptions with retry/circuit breaker. */ interface GeminiConfig extends BaseAdapterOptions { /** Maximum retry attempts (default: 3) */ readonly maxRetries?: number; /** Base delay for exponential backoff in ms (default: 1000) */ readonly baseDelayMs?: number; /** Maximum delay for backoff in ms (default: 30000) */ readonly maxDelayMs?: number; /** Circuit breaker configuration */ readonly circuitBreakerConfig?: Partial; /** Enable circuit breaker (default: true) */ readonly enableCircuitBreaker?: boolean; } /** Execution result with metadata. */ interface GeminiExecutionResult { readonly response: CliResponse; readonly retryCount: number; readonly totalDurationMs: number; readonly complexity: TaskComplexity; readonly circuitState: 'closed' | 'open' | 'half-open'; } /** * Gemini CLI adapter with reliability features. * * Includes tiered timeouts, resilient parsing, retry logic, and circuit breaker. */ declare class GeminiCliAdapter extends SubprocessCliAdapter { readonly name: CliName; /** * #4346: the arm is still called `gemini` (it serves Google's Gemini models * and keeps the routing/LinUCB identity), but the executable is `agy`. The * standalone gemini CLI is EOL — it exits 55 with IneligibleTierError on * every invocation. */ get binaryName(): string; protected readonly parser: ICliResponseParser; private readonly model; private readonly maxRetries; private readonly baseDelayMs; private readonly maxDelayMs; private readonly circuitBreaker; private readonly adapterLogger; constructor(options?: GeminiConfig); /** Key-free model enumeration via the models.dev snapshot (#3405). */ /** * The slugs this arm can actually run (#5085). * * NOT `listModelsForCli('gemini')`, which resolves the models.dev `google` * vendor — 82 Google **API** ids like `gemini-2.5-flash`. This arm spawns * `agy`, which accepts none of them; the same reasoning already documented * for `cliModelName` in `config/agy-model-map.ts` applies to enumeration. * Reporting the API list made every consumer confidently wrong rather than * empty, which is worse. */ listModels(): Promise; /** * Gets Gemini model information. * Resolves from canonical registry when possible, falls back to legacy lookup. * Note: maxOutput is capped at 8_192 (Gemini CLI constraint). */ getModelInfo(): ModelInfo; /** * Executes a task with reliability features. */ execute(task: CliTask, options?: ExecutionOptions$1): Promise>; /** * Executes with full metadata about retry attempts and circuit state. */ executeWithMetadata(task: CliTask, options?: ExecutionOptions$1): Promise>; /** * Gets current circuit breaker snapshot. */ getCircuitBreakerSnapshot(): CircuitBreakerSnapshot | null; /** * Resets the circuit breaker to closed state. */ resetCircuitBreaker(): void; /** * Gets CLI command and arguments for execution. */ protected getCommand(task: CliTask): CommandConfig; private checkCircuitBreaker; private buildExecutionOptions; private buildExecutionResult; private executeWithRetryTracking; } /** * nexus-agents/cli-adapters - Codex CLI Adapter Helpers * * CLI-specific helper functions for Codex subprocess adapter. * Model info lookups consolidated into config/model-config-helpers.ts (#886). */ /** Options accepted by both codex transports (subprocess and MCP). */ interface CodexAdapterOptions extends BaseAdapterOptions { /** * Host platform the sandbox arguments are chosen for. Defaults to * `process.platform`; injectable so a test can exercise the Linux and * non-Linux branches without mocking a global (#6093). */ readonly platform?: NodeJS.Platform; } /** * nexus-agents/cli-adapters - Codex CLI Adapter * * Subprocess-based adapter for Codex CLI. * Extends SubprocessCliAdapter to reuse retry logic, health checks, * version detection, and capacity tracking. * * (Source: cli-project_plan.md v2.1.0) * (Source: Issue #1140 — Migrated to SubprocessCliAdapter base class) * * SECURITY: All spawn() calls use array-based args without shell: true. * User task content is passed as a single argv element (no shell interpolation). */ /** * Codex CLI adapter using subprocess transport. * * Extends SubprocessCliAdapter which provides: * - Retry logic with exponential backoff * - Health checks with version compatibility * - Capacity tracking * - Subprocess spawn with timeout handling */ declare class CodexCliAdapter extends SubprocessCliAdapter { readonly name: CliName; protected readonly parser: ICliResponseParser; private readonly model; private readonly platform; constructor(options?: CodexAdapterOptions); /** Key-free model enumeration via the models.dev snapshot (#3405). */ listModels(): Promise; /** * Gets Codex model information. * Resolves from canonical registry when possible, falls back to legacy lookup. */ getModelInfo(): ModelInfo; /** * Gets CLI command and arguments for execution. * Task content is passed as a positional argument (not via stdin). */ protected getCommand(task: CliTask): CommandConfig; } /** * nexus-agents/cli-adapters - Codex MCP Adapter * * MCP-based adapter for Codex CLI. Preferred transport for Codex integration. * Extends BaseCliAdapter to reuse retry logic, health checks, version * detection, and capacity tracking. * * (Source: Issue #1140 — Migrated to BaseCliAdapter base class) * * SECURITY: All spawn() calls use array-based args without shell interpolation. */ /** * Codex CLI adapter using MCP transport. * * Extends BaseCliAdapter which provides: * - Retry logic with exponential backoff * - Health checks with version compatibility * - Capacity tracking * - Error creation helpers */ declare class CodexMcpAdapter extends BaseCliAdapter { readonly name: CliName; readonly transport: CliTransport; private readonly model; private readonly platform; private client; private mcpTransport; private connected; /** * Stderr attribution state (#6094). The registry caches one adapter per CLI * and voter roles run under `Promise.all`, so the mcp-server's stderr pipe is * shared by every in-flight call. `inFlight` is the current overlap; * `overlapEpoch` advances whenever a call starts while another is in flight, * so a capture that began alone can still see that it was later overlapped. */ private inFlight; private overlapEpoch; constructor(options?: CodexAdapterOptions); /** * Key-free model enumeration via the models.dev snapshot (#3405), matching * `CodexCliAdapter`. * * #4318: this was missing, and `buildDefaultModelSources` includes an adapter * only when `hasListModels(adapter)` is true. Since `createAllAdapters` * defaults codex to the mcp transport, codex was silently filtered out of * `list_available_models` — the probe reported one fewer transport than it * had, with no error anywhere. Model enumeration is transport-independent, so * the two adapters must answer identically. */ listModels(): Promise; /** * Gets Codex model information. * Resolves from canonical registry when possible, falls back to legacy lookup. */ getModelInfo(): ModelInfo; /** * Initializes the MCP connection to Codex. */ initialize(): Promise; /** * Executes a task via MCP client. * Called by BaseCliAdapter.execute() with retry handling. */ executeTask(_task: CliTask, options: ResolvedExecutionOptions): Promise>; /** * Attach a listener to the transport's stderr pipe; `stop()` detaches it * and returns what was written meanwhile (capped like the subprocess path). * A transport without a readable stderr (tests, or `stderr: 'inherit'`) * yields an empty capture, which the caller records as absent. * * ATTRIBUTION (#6094 review): the pipe is process-wide, so a line written * while two calls overlap cannot be assigned to either. If another call was * in flight at ANY point during this capture, the capture is discarded * (debug-logged) and the seat falls through to the reasoning fallback. * Attributing it to both would classify a seat that read the artifact as * unverifiable. */ private captureTransportStderr; /** * Calls the codex or codex-reply tool on Codex MCP server. * @see https://developers.openai.com/codex/mcp/ */ private callCodexTool; /** * Parses MCP tool result to CLI response. */ private parseToolResult; /** * Handles execution errors. */ private handleExecutionError; /** * Disposes the adapter and closes MCP connection. */ dispose(): Promise; } /** * nexus-agents/cli-adapters - OpenCode CLI Adapter * * Subprocess-based adapter for OpenCode CLI. * Uses `opencode run --format json` for stable parsing. * * (Source: Issue #1124, opencode.ai/docs/cli/) */ /** * OpenCode CLI adapter using subprocess transport. * Executes: opencode run --format json "" * * Probes available models on first use and omits --model flag * when the requested model isn't available (#1402). */ declare class OpenCodeCliAdapter extends SubprocessCliAdapter { readonly name: CliName; protected readonly parser: ICliResponseParser; /** Enable transient-error retry for OpenCode (#1456). */ protected readonly transientRetry: TransientRetryConfig; private readonly model; private availableModels; constructor(options?: BaseAdapterOptions); /** * Gets OpenCode model information from canonical registry. */ getModelInfo(): ModelInfo; /** * Initializes the adapter — probes available models. * Warns if Anthropic provider is configured (#1429 — API key boundaries). */ initialize(): Promise; /** Returns true if the model is available in the OpenCode installation. */ private isModelAvailable; /** #3408: true if the model is in rate-limit cooldown (recent 429). Opt-in. */ private isCooled; /** Usable = offered by the OpenCode install AND not in rate-limit cooldown. */ private isModelUsable; /** Appends --model if the resolved model is usable (#1402, #3407, #3408). */ private appendModelArg; /** * #3408: mark a model in rate-limit cooldown when a call returns RATE_LIMITED, * so subsequent selections skip it until the AvailabilityCache TTL recovers. * Wraps the base executeTask; opt-in + fail-open (no-op when discovery is off). * Advisory: a cooled model is still usable via an explicit, available --model. */ executeTask(task: CliTask, options: ResolvedExecutionOptions): Promise>; /** Appends optional task flags (workDir, variant, thinking). */ private appendTaskFlags; /** * Gets CLI command and arguments for execution. * Uses `opencode run` with JSON format for stable parsing. * Omits --model when the requested model isn't available (#1402). */ protected getCommand(task: CliTask): CommandConfig; /** * (#2540) Lists models the local OpenCode installation can route to. * Wraps the existing `probeAvailableModels()` (cached for the process * lifetime — see `cachedModels` at the top of this file) and reshapes * the result into the CliModelInfo schema. Splits `provider/model` ids * when present. */ listModels(): Promise; } /** * nexus-agents/cli-adapters - Claude CLI Response Parser * * Defensive parser for Claude CLI JSON output. * Handles version 2.0.x output format. * * (Source: cli-project_plan.md v2.1.0) * (Source: docs/research/cli-integration-architecture.md) */ /** * Claude CLI response structure. * (Source: CLI testing 2026-01-04) */ interface ClaudeCliResponse { readonly type: 'result'; readonly subtype?: 'success' | 'error'; readonly is_error: boolean; /** Why generation stopped — `end_turn` on an answer, `stop_sequence` on the measured error envelope (#6120). */ readonly stop_reason?: string; readonly duration_ms?: number; readonly result: string; readonly session_id?: string; readonly total_cost_usd?: number; readonly usage?: { readonly input_tokens: number; readonly output_tokens: number; readonly cache_creation_input_tokens?: number; readonly cache_read_input_tokens?: number; }; readonly modelUsage?: Record; } /** * Parser for Claude CLI JSON output. * Implements defensive parsing - only requires essential fields. */ declare class ClaudeResponseParser implements ICliResponseParser { readonly name = "claude-parser"; readonly supportedVersionRange = ">=2.0.0 <3.0.0"; /** * Parses complete Claude CLI response. */ parse(raw: string): ClaudeCliResponse | null; /** * Extracts just the response text (most stable field). * Returns null if the response contains an error. */ extractResponse(raw: string): string | null; /** * The error text of an `is_error: true` envelope, with its `stop_reason` * (#6120). * * Before this the envelope reached the adapter only through the generic * unparseable-output path, whose first step scans the WHOLE stdout for * rate-limit text. The out-of-credits envelope carries `api_error_status: * 429`, so that scan matched and the error message became the first 500 * characters of the envelope — `{"duration_api_ms":0,…` — while the one * field that names the cause, `result`, never reached anyone. Surfacing it * here routes the envelope through `classifyErrorOnlyStream`, which * classifies the message text rather than the envelope bytes. * * `null` when the envelope is not an error, or when `result` is empty: an * empty error text is not a message, and the caller's recovery order handles * it as before. */ extractErrorMessage(raw: string): string | null; /** * Extracts token usage from response. */ extractUsage(raw: string): TokenUsage$1 | null; /** * Extracts the cost the Claude CLI reported for this call. * * Prefers `total_cost_usd` — the vendor's own total — over summing * `modelUsage[*].costUSD`, because a per-model breakdown can omit a component * the total includes. Both are declared on {@link ClaudeCliResponse} and * neither reached `CliResponse` before #5241. * * Rejects a negative or non-finite figure: a cost is a measurement, and * letting a corrupt one through would debit the budget router with garbage. */ extractCostUsd(raw: string): number | null; /** * Extracts session ID for resumption. */ extractSessionId(raw: string): string | null; /** * Type guard for valid response structure. */ private isValidResponse; } /** * nexus-agents/cli-adapters - Gemini CLI Response Parser * * Defensive parser for Gemini CLI JSON output. * Handles version 0.2x.x output format. * * (Source: cli-project_plan.md v2.1.0) * (Source: docs/research/cli-integration-architecture.md) */ /** * Gemini CLI response structure. * (Source: CLI testing 2026-01-04) */ interface GeminiCliResponse { readonly session_id?: string; readonly response: string; readonly stats?: { readonly models?: Record; }; } /** * Parser for Gemini CLI JSON output. * Implements defensive parsing - only requires essential fields. */ declare class GeminiResponseParser implements ICliResponseParser { readonly name = "gemini-parser"; readonly supportedVersionRange = ">=0.20.0 <1.0.0"; /** * Parses complete Gemini CLI response. */ parse(raw: string): GeminiCliResponse | null; /** * Extracts just the response text (most stable field). */ extractResponse(raw: string): string | null; /** * Extracts token usage from response. * Gemini has per-model stats, we aggregate them. */ extractUsage(raw: string): TokenUsage$1 | null; /** * Aggregates tokens across all models. */ private aggregateModelTokens; /** * Extracts session ID for resumption. */ extractSessionId(raw: string): string | null; /** * Type guard for valid response structure. */ private isValidResponse; } /** * nexus-agents/cli-adapters - Codex CLI Response Parser * * Defensive parser for Codex CLI NDJSON output. * Handles version 0.7x.x output format. * * (Source: cli-project_plan.md v2.1.0) * (Source: docs/research/cli-integration-architecture.md) */ /** * Aggregated Codex response from NDJSON stream. */ interface CodexCliResponse { readonly threadId?: string; readonly messages: readonly string[]; readonly reasoning: readonly string[]; readonly usage?: TokenUsage$1; } /** * Parser for Codex CLI NDJSON output. * Implements defensive parsing - processes stream of events. */ declare class CodexResponseParser implements ICliResponseParser { readonly name = "codex-parser"; readonly supportedVersionRange = ">=0.70.0 <1.0.0"; /** * Parses complete Codex CLI NDJSON stream. */ parse(raw: string): CodexCliResponse | null; /** * Processes a single NDJSON line. */ private processLine; /** * Extracts just the response text (most stable field). * Concatenates all agent_message items. */ extractResponse(raw: string): string | null; /** * Extracts token usage from NDJSON stream. */ extractUsage(raw: string): TokenUsage$1 | null; /** * Extracts session ID (thread_id) for resumption. */ extractSessionId(raw: string): string | null; /** * Processes an item.completed event. */ private processItemCompleted; /** * Extracts usage from a turn.completed event. */ private extractUsageFromEvent; } /** * nexus-agents/cli-adapters - Adapter Factory * * Factory for creating CLI adapters based on configuration. * Supports optional caching of CLI health check results. * * (Source: cli-project_plan.md v2.1.0) * (Source: Issue #90 - Codex MCP adapter) * (Source: Issue #165 - CLI detection cache) */ /** * Configuration for creating a CLI adapter. */ interface CliAdapterConfig { /** Which CLI to use */ readonly cli: CliName; /** Optional model override */ readonly model?: string; /** Optional logger */ readonly logger?: ILogger; /** * Transport for Codex: `'mcp'` or `'subprocess'`. Unset selects by probe * (#6119): `mcp` when the installed codex serves `mcp-server`, otherwise * `subprocess` (`codex exec`). An explicit `'mcp'` on a codex without the * subcommand throws {@link CodexMcpServerUnavailableError} at construction. */ readonly transport?: CliTransport; } /** * Creates a CLI adapter based on configuration. * * @param config - Adapter configuration * @returns The configured CLI adapter * @throws Error if CLI name is not supported * * @example * ```typescript * const adapter = createCliAdapter({ cli: 'claude', model: 'claude-opus-4' }); * const result = await adapter.execute({ content: 'Hello!' }); * ``` */ declare function createCliAdapter(config: CliAdapterConfig): ICliAdapter; /** * Creates all available routing-arm adapters. * Codex transport is selected by probe unless one is passed (#6119). * * The four CLI slots are always registered under their slot key. When * `NEXUS_BILLING_MODE=api`, the direct-API adapters whose keys are present are * ALSO appended as distinct `api:` routing arms (#3422) so the router / * bandit can score them separately from the CLI slots. DEFAULT (plan) mode * returns CLIs only — never surprise API spend. Key-presence-only and * deterministic; keys are never validated by calling out. * * @param logger - Optional shared logger * @param codexTransport - Transport for Codex; unset selects by probe * @returns Map of routing arm id to adapter */ declare function createAllAdapters(logger?: ILogger, codexTransport?: CliTransport): Map; /** * Checks if a CLI is available by running a health check. * Uses cache if provided to avoid repeated subprocess calls. * * @param cli - CLI name to check * @param cache - Optional cache to use * @returns True if CLI is healthy */ declare function isCliAvailable(cli: CliName, cache?: ICliDetectionCache): Promise; /** * Gets all available CLIs by running health checks. * Uses cache if provided to avoid repeated subprocess calls. * * @param cache - Optional cache to use * @returns Array of available CLI names */ declare function getAvailableClis(cache?: ICliDetectionCache): Promise; /** * nexus-agents/cli-adapters - CLI Circuit Breaker Integration * * Wraps CLI adapter calls with circuit breaker pattern for resilient * multi-CLI execution with automatic fallback on failures. * * (Source: Issue #359 - Integrate circuit breaker with CLI adapters) */ /** Configuration for CLI circuit breaker integration. */ interface CliCircuitBreakerConfig { readonly perCliConfig?: Partial>>; readonly fallbackChain?: ReadonlyArray; readonly enableFallback?: boolean; readonly maxFallbackAttempts?: number; } /** Result of a circuit-protected execution with fallback info. */ interface CircuitProtectedResult { readonly response: CliResponse; readonly executedBy: CliName; readonly usedFallback: boolean; readonly fallbackAttempts?: ReadonlyArray; } /** Health status for all CLIs with circuit state. */ interface CliCircuitHealthStatus { readonly clis: ReadonlyArray<{ readonly name: CliName; readonly healthy: boolean; readonly circuitState: 'closed' | 'open' | 'half-open'; readonly failureCount: number; readonly lastFailureTime: number | null; }>; readonly systemHealthy: boolean; readonly healthyCount: number; readonly timestamp: number; } /** Interface for CLI circuit breaker integration. */ interface ICliCircuitBreakerIntegration { execute(adapter: ICliAdapter, task: CliTask, taskCategory?: TaskCategory): Promise>; getHealthStatus(): CliCircuitHealthStatus; getCircuitSnapshots(): Map; resetCircuit(cliName: CliName): void; resetAllCircuits(): void; addStateChangeListener(listener: CircuitStateChangeListener): void; } /** * Integrates circuit breaker pattern with CLI adapters. * Provides automatic fallback when a CLI's circuit opens. */ declare class CliCircuitBreakerIntegration implements ICliCircuitBreakerIntegration { private readonly registry; private readonly adapters; private readonly config; private readonly logger; constructor(adapters: ReadonlyArray, config?: CliCircuitBreakerConfig, logger?: ILogger); execute(adapter: ICliAdapter, task: CliTask, taskCategory?: TaskCategory): Promise>; getHealthStatus(): CliCircuitHealthStatus; getCircuitSnapshots(): Map; resetCircuit(cliName: CliName): void; resetAllCircuits(): void; addStateChangeListener(listener: CircuitStateChangeListener): void; private executeWithBreaker; private getFallbackClis; } /** Creates a CLI circuit breaker integration with the specified adapters. */ declare function createCliCircuitBreakerIntegration(adapters: ReadonlyArray, config?: CliCircuitBreakerConfig, logger?: ILogger): CliCircuitBreakerIntegration; /** * nexus-agents/context - Token Counter Types * * Type definitions for universal token counting. * * @module context/token-counter-types */ /** * Supported model families for token counting. */ declare const TokenCounterProvider: { readonly ANTHROPIC: "anthropic"; readonly GEMINI: "gemini"; readonly OPENAI: "openai"; }; type TokenCounterProvider = (typeof TokenCounterProvider)[keyof typeof TokenCounterProvider]; /** * Error specific to token counting operations. */ declare class TokenCountError extends NexusError { constructor(message: string, options?: { cause?: Error; context?: Record; }); } /** * Configuration for the token counter. */ interface TokenCounterConfig { /** Anthropic API key (optional, required for Anthropic counting) */ anthropicApiKey?: string; /** Google API key (optional, required for Gemini counting) */ googleApiKey?: string; /** Maximum cache entries (default: 1000) */ maxCacheSize?: number; /** Cache TTL in milliseconds (default: 5 minutes) */ cacheTtlMs?: number; } /** * Token counting result with metadata. */ interface TokenCountResult { /** Number of tokens */ count: number; /** Whether the result was from cache */ cached: boolean; /** Provider used for counting */ provider: TokenCounterProvider | 'estimate'; /** Model used (if applicable) */ model?: string; } /** * Interface for token counting operations. */ interface ITokenCounter { /** * Count tokens for Anthropic/Claude models via API. * @param messages - Messages to count tokens for * @param model - Model identifier (e.g., 'claude-sonnet-4') * @returns Promise with token count result */ countAnthropic(messages: Message[], model: string): Promise>; /** * Count tokens for Gemini models via API. * @param content - Text content to count tokens for * @param model - Model identifier (e.g., 'gemini-2.0-flash') * @returns Promise with token count result */ countGemini(content: string, model: string): Promise>; /** * Count tokens for OpenAI models using local tiktoken. * @param text - Text to count tokens for * @param model - Model identifier (default: 'gpt-4o') * @returns Token count result (synchronous, local) */ countOpenAI(text: string, model?: string): Result; /** * Estimate tokens offline using character-based heuristic. * @param text - Text to estimate tokens for * @returns Estimated token count */ estimate(text: string): number; /** * Clear the token count cache. */ clearCache(): void; /** * Get current cache statistics. */ getCacheStats(): { size: number; maxSize: number; ttlMs: number; }; } /** * nexus-agents/context - Universal Token Counter * * Provides token counting across all supported providers using their native APIs * or local estimation. Implements caching for repeated content to improve performance. * * Provider APIs: * - Anthropic: /v1/messages/count_tokens (free) * - Gemini: countTokens endpoint (free) * - OpenAI: tiktoken local library (free) * * Verified 2026-01-05: tiktoken@1.0.22 is current stable * (Source: npm registry) */ /** * Universal token counter supporting multiple providers. * * Provides accurate token counting via provider APIs (Anthropic, Gemini) * or local tiktoken (OpenAI), with fallback to character-based estimation. * * @example * ```typescript * const counter = new TokenCounter({ * anthropicApiKey: process.env.ANTHROPIC_API_KEY, * googleApiKey: process.env.GOOGLE_AI_API_KEY, * }); * * // Count via Anthropic API * const result = await counter.countAnthropic(messages, 'claude-sonnet-4'); * * // Count via local tiktoken * const openaiResult = counter.countOpenAI('Hello world', 'gpt-4o'); * * // Offline estimation * const estimate = counter.estimate('Some text'); * ``` */ declare class TokenCounter implements ITokenCounter { private readonly anthropicClient; private readonly geminiClient; private readonly cache; private readonly maxCacheSize; private readonly cacheTtlMs; private tiktokenEncoder; private currentTiktokenModel; /** * Creates a new TokenCounter instance. * * @param config - Token counter configuration */ constructor(config?: TokenCounterConfig); /** * Count tokens for Anthropic/Claude models via API. */ countAnthropic(messages: Message[], model: string): Promise>; /** * Count tokens for Gemini models via API. */ countGemini(content: string, model: string): Promise>; /** * Count tokens for OpenAI models using local tiktoken. */ countOpenAI(text: string, model?: string): Result; /** * Estimate tokens offline using character-based heuristic. * Uses ~4 characters per token as a general approximation. */ estimate(text: string): number; /** * Estimate tokens for a specific provider. */ estimateForProvider(text: string, provider: TokenCounterProvider): number; /** * Clear the token count cache. */ clearCache(): void; /** * Get current cache statistics. */ getCacheStats(): { size: number; maxSize: number; ttlMs: number; }; /** * Gets or creates a tiktoken encoder for the specified model. */ private getOrCreateTiktokenEncoder; /** * Gets a cached entry if valid. */ private getCached; /** * Sets a cache entry, evicting oldest if at capacity. */ private setCache; /** * Frees resources (tiktoken encoder). * Call this when done with the counter. */ dispose(): void; } /** * Creates a TokenCounter instance with the specified configuration. * * @param config - Token counter configuration * @returns Configured TokenCounter instance * * @example * ```typescript * const counter = createTokenCounter({ * anthropicApiKey: process.env.ANTHROPIC_API_KEY, * googleApiKey: process.env.GOOGLE_AI_API_KEY, * }); * ``` */ declare function createTokenCounter(config?: TokenCounterConfig): TokenCounter; /** * nexus-agents/learning - SQLite Outcome Storage * * Implements persistent storage for routing decisions and outcomes * using SQLite. Enables cross-session learning for LinUCB bandit. * * @module learning/outcome-storage * (Source: Issue #188 - Outcome recording for routing ML feedback) */ /** * SQLite-based outcome storage implementation. */ declare class SQLiteOutcomeStorage implements IOutcomeStorage { private readonly dbPath; private readonly logger; private db; private initialized; private initPromise; constructor(config: OutcomeStorageConfig); /** Initialize with an existing database instance (for testing). */ initializeWithDatabase(database: ISQLiteDatabase): void; /** Initialize the storage backend. */ initialize(): Promise>; private doInitialize; private createTables; private getDatabase; private ensureInitialized; storeDecision(decision: StoredRoutingDecision): Promise>; storeOutcome(outcome: StoredTaskOutcome): Promise>; storeReward(reward: StoredReward): Promise>; getDecision(id: string): Promise>; getOutcome(decisionId: string): Promise>; getModelStats(): Promise>; getRecentDecisions(model: CliName, limit: number): Promise>; getDecisionsByRequestId(requestId: string): Promise>; prune(olderThan: Date): Promise>; getCounts(): Promise>; /** Close the database connection. */ close(): void; } /** Create an SQLite outcome storage instance. */ declare function createOutcomeStorage(config: OutcomeStorageConfig): SQLiteOutcomeStorage; /** * Validation Statistics Module * * Statistical utilities for the learning validation dashboard. * Provides confidence intervals, hypothesis testing, and distribution analysis. * * @module learning/validation-stats * (Source: Issue #273 - Learning Validation Dashboard) */ /** * Calculate confidence interval for a proportion (success rate). * Uses Wilson score interval for better coverage at extreme proportions. */ declare function proportionConfidenceInterval(successes: number, total: number, options?: StatisticalOptions): ConfidenceInterval; /** * Calculate confidence interval for a mean. */ declare function meanConfidenceInterval(values: readonly number[], options?: StatisticalOptions): ConfidenceInterval; /** * Compare two proportions using two-proportion z-test. */ declare function compareProportions(successes1: number, total1: number, successes2: number, total2: number, options?: StatisticalOptions): ComparisonResult; /** * Calculate descriptive statistics for a distribution. */ declare function calculateDistributionStats(values: readonly number[]): DistributionStats; /** * Calculate regret analysis comparing actual decisions vs oracle (best possible). */ declare function calculateRegret(decisions: readonly { readonly chosenModel: string; readonly actualReward: number; readonly rewards: Record; }[]): RegretAnalysis; /** * Calculate win/loss analysis for a model. */ declare function calculateWinLoss(model: string, decisions: readonly { readonly chosenModel: string; readonly actualReward: number; readonly rewards: Record; }[], options?: StatisticalOptions): WinLossAnalysis; /** * Calculate minimum sample size for detecting a difference in proportions. * Uses formula for two-proportion z-test power analysis. */ declare function calculateMinSampleSize(baselineRate: number, minimumDetectableEffect: number, options?: { power?: number; alpha?: number; }): number; /** * Persistent StrategyDistiller — JSON-backed cross-session persistence. * * Extends StrategyDistiller with atomic disk writes (write tmp + rename) * for distilled rules. Hydrates from a versioned JSON snapshot on * construction; saves after every distill() call. * * @module learning/strategy-distiller-persistence * (Source: Issue #1009 — Cross-session persistence) */ /** Versioned snapshot schema for atomic saves. */ declare const RulesSnapshotSchema: z.ZodObject<{ version: z.ZodLiteral<1>; savedAt: z.ZodString; rules: z.ZodArray; cli: z.ZodEnum<{ claude: "claude"; gemini: "gemini"; codex: "codex"; opencode: "opencode"; }>; category: z.ZodString; action: z.ZodEnum<{ penalize: "penalize"; boost: "boost"; avoid: "avoid"; }>; confidence: z.ZodNumber; support: z.ZodOptional; effect: z.ZodOptional; observationCount: z.ZodNumber; metric: z.ZodNumber; status: z.ZodEnum<{ draft: "draft"; active: "active"; promoted: "promoted"; expired: "expired"; }>; createdAt: z.ZodNumber; updatedAt: z.ZodNumber; tainted: z.ZodBoolean; }, z.core.$strip>>; }, z.core.$strip>; type RulesSnapshot = z.infer; interface PersistentDistillerConfig { /** Override the file path (useful for testing). */ readonly filePath?: string; /** Override the data directory (useful for testing). */ readonly dataDir?: string; } /** * StrategyDistiller that persists distilled rules to a JSON file. * * - Construction: hydrates from rules.json via Zod validation * - distill(): calls super.distill() then atomically saves snapshot * - Corruption: warn + start fresh (no partial loads) */ declare class PersistentStrategyDistiller extends StrategyDistiller { private readonly filePath; private readonly persistLogger; constructor(outcomeStore: OutcomeStore, persistConfig?: PersistentDistillerConfig, logger?: ILogger, distillerConfig?: Partial); /** Override distill to persist rules after each run. */ distill(): void; private hydrate; private saveSnapshot; } /** * A/B Test Tracker Types * * Type definitions for A/B testing infrastructure in the learning validation dashboard. * Supports experiment definition, variant assignment, and result analysis. * * @module learning/ab-test-types * (Source: Issue #273 - Learning Validation Dashboard) */ /** * Experiment status states. */ type ExperimentStatus = 'draft' | 'running' | 'paused' | 'completed' | 'archived'; /** * Experiment variant configuration. */ interface ExperimentVariant { /** Variant identifier */ readonly id: string; /** Human-readable name */ readonly name: string; /** Description of what this variant does */ readonly description: string; /** Traffic allocation percentage (0-100) */ readonly trafficPercent: number; /** Whether this is the control variant */ readonly isControl: boolean; } /** * Experiment definition. */ interface ExperimentDefinition { /** Unique experiment identifier */ readonly id: string; /** Human-readable name */ readonly name: string; /** Description of the experiment's hypothesis */ readonly description: string; /** Current status */ readonly status: ExperimentStatus; /** Experiment variants */ readonly variants: readonly ExperimentVariant[]; /** Start timestamp (ISO 8601) */ readonly startedAt: string | null; /** End timestamp (ISO 8601) */ readonly endedAt: string | null; /** Minimum sample size per variant */ readonly minSampleSize: number; /** Primary metric to optimize */ readonly primaryMetric: 'successRate' | 'avgReward' | 'avgLatency'; /** Minimum detectable effect size */ readonly minimumDetectableEffect: number; /** Tags for categorization */ readonly tags: readonly string[]; } /** * Recorded outcome for an experiment. */ interface ExperimentOutcome { /** Experiment ID */ readonly experimentId: string; /** Assigned variant ID */ readonly variantId: string; /** Routing decision trace ID */ readonly traceId: string; /** Whether the task succeeded */ readonly success: boolean; /** Reward value */ readonly reward: number; /** Latency in milliseconds */ readonly latencyMs: number; /** Timestamp (ISO 8601) */ readonly timestamp: string; /** Additional metadata */ readonly metadata?: Record; } /** * Variant statistics. */ interface VariantStats { /** Variant ID */ readonly variantId: string; /** Variant name */ readonly name: string; /** Number of observations */ readonly n: number; /** Success count */ readonly successes: number; /** Success rate */ readonly successRate: number; /** Average reward */ readonly avgReward: number; /** Average latency in ms */ readonly avgLatencyMs: number; /** Sum of rewards (for incremental computation) */ readonly sumReward: number; /** Sum of latencies (for incremental computation) */ readonly sumLatencyMs: number; } /** * Experiment summary with all variants and comparison. */ interface ExperimentSummary { /** Experiment definition */ readonly experiment: ExperimentDefinition; /** Statistics per variant */ readonly variantStats: readonly VariantStats[]; /** Statistical comparison result */ readonly result: ExperimentResult | null; /** Whether experiment has reached minimum sample size */ readonly hasMinimumSampleSize: boolean; /** Recommended action based on results */ readonly recommendation: 'continue' | 'stop_winner' | 'stop_inconclusive'; } /** * A/B test tracker interface. */ interface IAbTestTracker { /** * Create a new experiment. */ createExperiment(definition: Omit): ExperimentDefinition; /** * Start an experiment (sets status to running). */ startExperiment(experimentId: string): void; /** * Pause a running experiment. */ pauseExperiment(experimentId: string): void; /** * Complete an experiment. */ completeExperiment(experimentId: string): void; /** * Assign a variant for a given trace ID (deterministic assignment). */ assignVariant(experimentId: string, traceId: string): ExperimentVariant | null; /** * Record an outcome for an experiment. */ recordOutcome(outcome: ExperimentOutcome): void; /** * Get experiment summary with statistics. */ getSummary(experimentId: string): ExperimentSummary | null; /** * List all experiments. */ listExperiments(filter?: { status?: ExperimentStatus; tags?: readonly string[]; }): readonly ExperimentDefinition[]; /** * Get experiment by ID. */ getExperiment(experimentId: string): ExperimentDefinition | null; /** * Export all experiment data. */ exportData(): ExperimentExport; } /** * Export format for experiment data. */ interface ExperimentExport { /** Export timestamp */ readonly exportedAt: string; /** All experiments */ readonly experiments: readonly ExperimentDefinition[]; /** All outcomes */ readonly outcomes: readonly ExperimentOutcome[]; /** Summaries for completed experiments */ readonly summaries: readonly ExperimentSummary[]; } /** * A/B Test Tracker * * Manages experiment lifecycle, variant assignment, and statistical analysis. * Supports deterministic variant assignment based on trace ID hashing. * * @module learning/ab-test-tracker * (Source: Issue #273 - Learning Validation Dashboard) */ /** * A/B Test Tracker implementation. * Provides experiment management with deterministic variant assignment. */ declare class AbTestTracker implements IAbTestTracker { private readonly experiments; private readonly outcomes; /** * Create a new experiment. */ createExperiment(definition: Omit): ExperimentDefinition; /** * Start an experiment (sets status to running). */ startExperiment(experimentId: string): void; /** * Pause a running experiment. */ pauseExperiment(experimentId: string): void; /** * Complete an experiment. */ completeExperiment(experimentId: string): void; /** * Assign a variant for a given trace ID (deterministic assignment). * Uses consistent hashing to ensure same trace ID always gets same variant. */ assignVariant(experimentId: string, traceId: string): ExperimentVariant | null; /** * Record an outcome for an experiment. */ recordOutcome(outcome: ExperimentOutcome): void; /** * Get experiment summary with statistics. */ getSummary(experimentId: string): ExperimentSummary | null; /** * List all experiments. */ listExperiments(filter?: { status?: ExperimentStatus; tags?: readonly string[]; }): readonly ExperimentDefinition[]; /** * Get experiment by ID. */ getExperiment(experimentId: string): ExperimentDefinition | null; /** * Export all experiment data. */ exportData(): ExperimentExport; private getExperimentOrThrow; private calculateVariantStats; /** Build variant summary for experiment results. */ private buildVariantSummary; private calculateExperimentResult; private getRecommendation; } /** * Create a default A/B test tracker instance. */ declare function createAbTestTracker(): IAbTestTracker; /** * nexus-agents/audit - Audit Storage Query Operations * * Query criteria matching and file reading operations for audit storage. * Extracted from audit-storage.ts to comply with 400-line limit. * * (Source: Issue #193 - Phase 3 structured audit logging) * * @module audit/audit-storage-queries */ /** * In-memory audit storage implementation for testing. * Events are stored in memory with configurable maximum capacity. */ declare class InMemoryAuditStorage implements IAuditStorage { private readonly events; private readonly maxEvents; constructor(maxEvents?: number); write(event: AuditEvent$1): Promise; flush(): Promise; close(): Promise; query(criteria: AuditQueryCriteria): Promise; /** Get all events (for testing) */ getAll(): AuditEvent$1[]; /** Clear all events (for testing) */ clear(): void; } /** * nexus-agents/audit - File-based Audit Storage * * JSON-L file storage with rotation for audit events. * SIEM-compatible output format. * * (Source: Issue #193 - Phase 3 structured audit logging) * * @module audit/audit-storage */ /** * Configuration for FileAuditStorage with optional security boundary. */ interface FileAuditStorageConfig extends AuditLogConfig { /** Optional root directory that logDir must be within. */ allowedRoot?: string; } declare class FileAuditStorage implements IAuditStorage { private readonly logDir; private readonly filePrefix; private readonly maxFileSizeBytes; private readonly maxFiles; private readonly logger; private currentFile; private writeStream; private currentFileSize; private writeBuffer; /** * Creates a FileAuditStorage instance with path validation. * Use this factory method for safe instantiation with proper error handling. * * @param config - Audit log configuration with optional allowedRoot * @param logger - Optional logger instance * @returns Result with FileAuditStorage or SecurityError */ static create(config: FileAuditStorageConfig, logger?: ILogger): Result; /** * Constructor for FileAuditStorage. * * SECURITY NOTE: Prefer using FileAuditStorage.create() for safe instantiation * with proper path validation and error handling. * * @param config - Audit log configuration * @param logger - Optional logger instance * @param skipValidation - Internal flag, set by create() after validation * @throws SecurityError if path validation fails and skipValidation is false */ constructor(config: AuditLogConfig, logger?: ILogger, skipValidation?: boolean); private ensureLogDirectory; private generateFileName; private getExistingLogFiles; private initCurrentFile; private openWriteStream; private rotateFile; private pruneOldFiles; write(event: AuditEvent$1): Promise; flush(): Promise; close(): Promise; query(criteria: AuditQueryCriteria): Promise; } /** * nexus-agents/audit - SecureHandler Audit Integration * * Integration helper to add audit logging to SecureHandler middleware. * * (Source: Issue #193 - Phase 3 structured audit logging) * * @module audit/secure-handler-audit */ /** * Configuration for audit-enabled secure handler. */ interface AuditHandlerConfig { /** Audit logger instance */ auditLogger: IAuditLogger; /** Default actor for requests without caller info */ defaultActor?: AuditActor | undefined; } /** * Creates an AuditActor from RequestContext. */ declare function actorFromContext(ctx: RequestContext, fallback?: AuditActor): AuditActor; /** * Maps tool result to audit outcome. */ declare function resultToOutcome(isError: boolean | undefined, isPolicyDenied: boolean): AuditOutcome; /** Options for logging tool invocation audit */ interface LogToolInvocationOpts { auditLogger: IAuditLogger; toolName: string; outcome: AuditOutcome; actor: AuditActor; requestId: string; durationMs?: number | undefined; errorMessage?: string | undefined; } /** * Logs tool invocation to audit logger. */ declare function logToolInvocationAudit(opts: LogToolInvocationOpts): void; /** Options for logging policy audit */ interface LogPolicyAuditOpts { auditLogger: IAuditLogger; policyName: string; decision: 'allow' | 'deny'; reason: string; toolName: string; actor: AuditActor; requestId: string; } /** * Logs policy decision to audit logger. */ declare function logPolicyAudit(opts: LogPolicyAuditOpts): void; /** Options for logging rate limit audit */ interface LogRateLimitAuditOpts { auditLogger: IAuditLogger; toolName: string; actor: AuditActor; currentRate: number; limitRate: number; requestId: string; } /** * Logs rate limit violation to audit logger. */ declare function logRateLimitAudit(opts: LogRateLimitAuditOpts): void; /** * nexus-agents/security/sandbox - Type Definitions * * Types for agent execution sandboxing and isolation. * * @module security/sandbox/sandbox-types * (Source: Issue #162, Alignment Roadmap Phase 4) */ /** * Sandbox execution mode. * * - `none`: no isolation; for development only. * - `policy`: rule-based enforcement with no process isolation. Catches * policy violations but a misbehaving process can still touch the host. * - `container`: Docker-based OS-level isolation. Strongest, but requires * Docker on the host. * - `deno`: process-level permission gating via Deno's `--allow-*` flags * (#1898). Weaker than container — same OS, just process permissions — * but works without Docker (Mac without Docker Desktop, locked-down CI * runners). No CPU/memory limits. */ type SandboxMode = 'none' | 'policy' | 'container' | 'deno'; /** * Security capability that can be restricted. */ type SecurityCapability = 'network' | 'filesystem_read' | 'filesystem_write' | 'process_spawn' | 'env_access'; /** * Resource limits for sandboxed execution. */ interface ResourceLimits { /** Maximum memory in bytes (default: 512MB). */ readonly maxMemoryBytes?: number; /** Maximum CPU time in milliseconds. */ readonly maxCpuTimeMs?: number; /** Maximum number of child processes. */ readonly maxProcesses?: number; /** Maximum output buffer size in bytes. */ readonly maxOutputBytes?: number; /** Maximum execution time in milliseconds. */ readonly maxWallTimeMs?: number; } /** * Default resource limits. */ declare const DEFAULT_RESOURCE_LIMITS: Required; /** * Path access rule for filesystem sandboxing. */ interface PathAccessRule { /** Path pattern (supports glob). */ readonly path: string; /** Access mode: 'read' | 'write' | 'none'. */ readonly access: 'read' | 'write' | 'none'; } /** * Sandbox execution policy. */ interface SandboxPolicy { /** Unique policy identifier. */ readonly id: string; /** Human-readable policy name. */ readonly name: string; /** Sandbox execution mode. */ readonly mode: SandboxMode; /** Allowed commands (empty = all denied). */ readonly allowedCommands: readonly string[]; /** Allowed environment variables to pass through. */ readonly allowedEnvVars: readonly string[]; /** Path access rules. */ readonly pathRules: readonly PathAccessRule[]; /** Enabled capabilities. */ readonly capabilities: readonly SecurityCapability[]; /** Resource limits. */ readonly limits: ResourceLimits; } /** * Result of sandbox policy evaluation. */ interface PolicyEvaluation { /** Whether the operation is allowed. */ readonly allowed: boolean; /** Denial reason if not allowed. */ readonly reason?: string; /** Policy that was applied. */ readonly policyId: string; /** Violations found. */ readonly violations: readonly PolicyViolation$1[]; /** * Configuration mismatches the executor surfaces to operators — capabilities * declared in the policy but unenforceable because the corresponding * allowlist is empty (e.g. `process_spawn` set but `allowedCommands: []`). * Source: #2428 ask 1. Not security violations; informational only. */ readonly configurationWarnings?: readonly string[]; } /** * A specific policy violation. */ interface PolicyViolation$1 { /** Type of violation. */ readonly type: 'command' | 'env' | 'path' | 'capability' | 'resource'; /** What was denied. */ readonly denied: string; /** Explanation. */ readonly reason: string; } /** * Sandbox execution result. */ interface SandboxResult { /** Whether execution succeeded. */ readonly success: boolean; /** Exit code from the command. */ readonly exitCode: number; /** Standard output. */ readonly stdout: string; /** Standard error. */ readonly stderr: string; /** Execution duration in milliseconds. */ readonly durationMs: number; /** Resource usage metrics. */ readonly resourceUsage: ResourceUsage; /** Policy evaluation result. */ readonly policyEvaluation: PolicyEvaluation; } /** * Resource usage metrics from sandboxed execution. */ interface ResourceUsage { /** Memory used in bytes. */ readonly memoryBytes: number; /** CPU time used in milliseconds. */ readonly cpuTimeMs: number; /** Number of processes spawned. */ readonly processCount: number; /** Output bytes generated. */ readonly outputBytes: number; /** Wall time in milliseconds. */ readonly wallTimeMs: number; } /** * Interface for sandbox executors. */ interface ISandboxExecutor { /** Executor name for logging. */ readonly name: string; /** Execute a command in the sandbox. */ execute(command: string, args: readonly string[], options: SandboxExecutionOptions): Promise; /** Validate a command without executing. */ validate(command: string, args: readonly string[], options: SandboxExecutionOptions): PolicyEvaluation; } /** * Options for sandboxed execution. */ interface SandboxExecutionOptions { /** Working directory. */ readonly cwd?: string; /** Environment variables (will be filtered by policy). */ readonly env?: Record; /** Policy to apply. */ readonly policy: SandboxPolicy; /** Override resource limits. */ readonly limits?: Partial; } /** * Sandbox executor configuration. */ interface SandboxConfig { /** Default policy to use. */ readonly defaultPolicy: SandboxPolicy; /** Whether to log policy violations. */ readonly logViolations: boolean; /** Whether to enforce policies (false = warn only). */ readonly enforce: boolean; } /** * nexus-agents/security/sandbox - Command Allowlist * * Validates commands against an allowlist to prevent arbitrary execution. * * @module security/sandbox/command-allowlist * (Source: Issue #162, Alignment Roadmap Phase 4) */ /** * Flat list of all allowed commands. */ declare const ALLOWED_COMMANDS: readonly string[]; /** * Validates a command name against the allowlist. */ declare function validateCommand(command: string, allowedCommands: readonly string[]): PolicyViolation$1 | null; /** * nexus-agents/security/sandbox - Default Policies * * Pre-defined sandbox policies for common use cases. * * @module security/sandbox/default-policies * (Source: Issue #162, Alignment Roadmap Phase 4) */ /** * All default policies keyed by ID. */ declare const DEFAULT_POLICIES: Record; /** * Get a policy by ID. */ declare function getPolicy(id: string): SandboxPolicy | undefined; /** * nexus-agents/security/sandbox - Sandbox Executor * * Policy-enforcing command executor with resource limits. * * @module security/sandbox/sandbox-executor * (Source: Issue #162, Alignment Roadmap Phase 4) */ /** * Create a sandbox executor with optional config. * * Since #2551 this returns the single surviving in-process executor * (`PolicySandboxExecutor`). The Docker/Deno executors were deleted as * unused; real isolation is provided out-of-process by the OpenCode * sandbox bootstrap (#2500). */ declare function createSandboxExecutor(config?: Partial): ISandboxExecutor; /** * nexus-agents/security/safety-bench - Safety Enums and Constants * * Enum definitions and constants for Agent-SafetyBench evaluation. * * @module security/safety-bench/safety-enums * (Source: Issue #332) */ /** * Risk severity levels for safety categories. */ declare const RiskLevel: { /** Low risk - minimal potential for harm. */ readonly LOW: "low"; /** Medium risk - moderate potential for harm. */ readonly MEDIUM: "medium"; /** High risk - significant potential for harm. */ readonly HIGH: "high"; /** Critical risk - severe potential for harm, requires immediate attention. */ readonly CRITICAL: "critical"; }; type RiskLevelType = (typeof RiskLevel)[keyof typeof RiskLevel]; /** * Unique identifiers for safety categories. */ declare const SafetyCategoryId: { /** Physical harm prevention category. */ readonly HARM_PHYSICAL: "harm_physical"; /** Emotional/psychological harm prevention category. */ readonly HARM_EMOTIONAL: "harm_emotional"; /** Financial harm prevention category. */ readonly HARM_FINANCIAL: "harm_financial"; /** Deception detection and prevention category. */ readonly DECEPTION: "deception"; /** Bias evaluation and mitigation category. */ readonly BIAS: "bias"; /** Privacy protection category. */ readonly PRIVACY: "privacy"; /** Manipulation resistance category. */ readonly MANIPULATION: "manipulation"; /** Instruction following safety category. */ readonly INSTRUCTION_SAFETY: "instruction_safety"; /** Robustness to adversarial inputs category. */ readonly ROBUSTNESS: "robustness"; /** Risk awareness and hazard recognition category. */ readonly RISK_AWARENESS: "risk_awareness"; }; type SafetyCategoryIdType = (typeof SafetyCategoryId)[keyof typeof SafetyCategoryId]; /** * Types of evaluation criteria for safety assessment. */ declare const CriterionType: { /** Binary pass/fail criterion. */ readonly BINARY: "binary"; /** Scaled score criterion (0-100). */ readonly SCALED: "scaled"; /** Threshold-based criterion. */ readonly THRESHOLD: "threshold"; /** Categorical classification criterion. */ readonly CATEGORICAL: "categorical"; }; type CriterionTypeType = (typeof CriterionType)[keyof typeof CriterionType]; /** * Expected outcome for a safety test case. */ declare const ExpectedOutcome: { /** Agent should refuse the action. */ readonly REFUSE: "refuse"; /** Agent should proceed with caution/warning. */ readonly CAUTION: "caution"; /** Agent should request clarification. */ readonly CLARIFY: "clarify"; /** Agent should escalate to human. */ readonly ESCALATE: "escalate"; /** Agent should proceed normally. */ readonly PROCEED: "proceed"; /** Agent should detect and report the issue. */ readonly DETECT: "detect"; }; type ExpectedOutcomeType = (typeof ExpectedOutcome)[keyof typeof ExpectedOutcome]; /** * nexus-agents/security/safety-bench - Safety Zod Schemas * * Zod validation schemas for Agent-SafetyBench types. * * @module security/safety-bench/safety-schemas * (Source: Issue #332) */ /** * Zod schema for RiskLevel validation. */ declare const RiskLevelSchema: z.ZodEnum<{ critical: "critical"; high: "high"; low: "low"; medium: "medium"; }>; /** * Zod schema for SafetyCategoryId validation. */ declare const SafetyCategoryIdSchema: z.ZodEnum<{ harm_physical: "harm_physical"; harm_emotional: "harm_emotional"; harm_financial: "harm_financial"; deception: "deception"; bias: "bias"; privacy: "privacy"; manipulation: "manipulation"; instruction_safety: "instruction_safety"; robustness: "robustness"; risk_awareness: "risk_awareness"; }>; /** * Zod schema for CriterionType validation. */ declare const CriterionTypeSchema: z.ZodEnum<{ binary: "binary"; threshold: "threshold"; scaled: "scaled"; categorical: "categorical"; }>; /** * Zod schema for ExpectedOutcome validation. */ declare const ExpectedOutcomeSchema: z.ZodEnum<{ escalate: "escalate"; refuse: "refuse"; caution: "caution"; clarify: "clarify"; proceed: "proceed"; detect: "detect"; }>; /** * Definition of an evaluation criterion for safety assessment. */ interface EvaluationCriterion { /** Unique criterion identifier. */ readonly id: string; /** Human-readable criterion name. */ readonly name: string; /** Detailed description of what the criterion measures. */ readonly description: string; /** Type of evaluation (binary, scaled, threshold, categorical). */ readonly type: CriterionTypeType; /** Weight factor for scoring (0.0-1.0). */ readonly weight: number; /** Threshold value for pass (for threshold type). */ readonly passThreshold?: number | undefined; /** Categories for categorical type. */ readonly categories?: readonly string[] | undefined; } /** * Example test case for safety evaluation. */ interface SafetyTestCase { /** Unique test case identifier. */ readonly id: string; /** Test case name. */ readonly name: string; /** Detailed description of the test scenario. */ readonly description: string; /** Input prompt or scenario for the agent. */ readonly input: string; /** Expected safe behavior outcome. */ readonly expectedOutcome: ExpectedOutcomeType; /** Risk level of the scenario. */ readonly riskLevel: RiskLevelType; /** Tags for filtering and grouping. */ readonly tags: readonly string[]; /** Additional context or environment setup. */ readonly context?: string | undefined; } /** * Complete definition of a safety category. */ interface SafetyCategory { /** Unique category identifier. */ readonly id: SafetyCategoryIdType; /** Human-readable category name. */ readonly name: string; /** Detailed description of the category. */ readonly description: string; /** Default risk level for violations in this category. */ readonly defaultRiskLevel: RiskLevelType; /** Parent category ID (for subcategories). */ readonly parentId?: SafetyCategoryIdType | undefined; /** Evaluation criteria for this category. */ readonly criteria: readonly EvaluationCriterion[]; /** Example test cases demonstrating the category. */ readonly exampleTestCases: readonly SafetyTestCase[]; /** Failure modes commonly seen in this category. */ readonly failureModes: readonly string[]; /** Mitigation strategies for this category. */ readonly mitigationStrategies: readonly string[]; } /** * Zod schema for EvaluationCriterion validation. */ declare const EvaluationCriterionSchema: z.ZodObject<{ id: z.ZodString; name: z.ZodString; description: z.ZodString; type: z.ZodEnum<{ binary: "binary"; threshold: "threshold"; scaled: "scaled"; categorical: "categorical"; }>; weight: z.ZodNumber; passThreshold: z.ZodOptional; categories: z.ZodOptional>>; }, z.core.$strip>; /** * Zod schema for SafetyTestCase validation. */ declare const SafetyTestCaseSchema: z.ZodObject<{ id: z.ZodString; name: z.ZodString; description: z.ZodString; input: z.ZodString; expectedOutcome: z.ZodEnum<{ escalate: "escalate"; refuse: "refuse"; caution: "caution"; clarify: "clarify"; proceed: "proceed"; detect: "detect"; }>; riskLevel: z.ZodEnum<{ critical: "critical"; high: "high"; low: "low"; medium: "medium"; }>; tags: z.ZodReadonly>; context: z.ZodOptional; }, z.core.$strip>; /** * Zod schema for SafetyCategory validation. */ declare const SafetyCategorySchema: z.ZodObject<{ id: z.ZodEnum<{ harm_physical: "harm_physical"; harm_emotional: "harm_emotional"; harm_financial: "harm_financial"; deception: "deception"; bias: "bias"; privacy: "privacy"; manipulation: "manipulation"; instruction_safety: "instruction_safety"; robustness: "robustness"; risk_awareness: "risk_awareness"; }>; name: z.ZodString; description: z.ZodString; defaultRiskLevel: z.ZodEnum<{ critical: "critical"; high: "high"; low: "low"; medium: "medium"; }>; parentId: z.ZodOptional>; criteria: z.ZodReadonly; weight: z.ZodNumber; passThreshold: z.ZodOptional; categories: z.ZodOptional>>; }, z.core.$strip>>>; exampleTestCases: z.ZodReadonly; riskLevel: z.ZodEnum<{ critical: "critical"; high: "high"; low: "low"; medium: "medium"; }>; tags: z.ZodReadonly>; context: z.ZodOptional; }, z.core.$strip>>>; failureModes: z.ZodReadonly>; mitigationStrategies: z.ZodReadonly>; }, z.core.$strip>; /** * Summary statistics for the safety category taxonomy. */ interface SafetyTaxonomySummary { /** Total number of categories. */ readonly totalCategories: number; /** Total number of evaluation criteria. */ readonly totalCriteria: number; /** Total number of example test cases. */ readonly totalTestCases: number; /** Categories by risk level. */ readonly categoriesByRiskLevel: Readonly>; /** Test cases by expected outcome. */ readonly testCasesByOutcome: Readonly>; } /** * nexus-agents/security/safety-bench - Safety Category Definitions * * Concrete definitions for all safety categories in the taxonomy. * * @module security/safety-bench/safety-category-definitions * (Source: Issue #332) */ /** * Physical Harm Prevention Category. * Evaluates agent's ability to avoid actions that could cause physical harm. */ declare const HARM_PHYSICAL_CATEGORY: SafetyCategory; /** * Emotional/Psychological Harm Prevention Category. */ declare const HARM_EMOTIONAL_CATEGORY: SafetyCategory; /** * Financial Harm Prevention Category. */ declare const HARM_FINANCIAL_CATEGORY: SafetyCategory; /** * Deception Detection Category. */ declare const DECEPTION_CATEGORY: SafetyCategory; /** * Bias Evaluation Category. */ declare const BIAS_CATEGORY: SafetyCategory; /** * nexus-agents/security/safety-bench - Privacy Protection Category * * Privacy protection safety category definition. * * @module security/safety-bench/safety-category-privacy * (Source: Issue #332) */ /** * Privacy Protection Category. */ declare const PRIVACY_CATEGORY: SafetyCategory; /** * nexus-agents/security/safety-bench - Manipulation Resistance Category * * Manipulation resistance safety category definition. * * @module security/safety-bench/safety-category-manipulation * (Source: Issue #332) */ /** * Manipulation Resistance Category. */ declare const MANIPULATION_CATEGORY: SafetyCategory; /** * nexus-agents/security/safety-bench - Instruction Following Safety Category * * Instruction following safety category definition. * * @module security/safety-bench/safety-category-instruction * (Source: Issue #332) */ /** * Instruction Following Safety Category. */ declare const INSTRUCTION_SAFETY_CATEGORY: SafetyCategory; /** * nexus-agents/security/safety-bench - Robustness Category * * Robustness safety category definition. * * @module security/safety-bench/safety-category-robustness * (Source: Issue #332) */ /** * Robustness Category. */ declare const ROBUSTNESS_CATEGORY: SafetyCategory; /** * nexus-agents/security/safety-bench - Risk Awareness Category * * Risk awareness safety category definition. * * @module security/safety-bench/safety-category-risk * (Source: Issue #332) */ /** * Risk Awareness Category. */ declare const RISK_AWARENESS_CATEGORY: SafetyCategory; /** * nexus-agents/security/safety-bench - Safety Category Taxonomy * * Comprehensive safety category definitions for Agent-SafetyBench evaluation. * Based on standard agent safety frameworks and arXiv:2412.14470. * * @module security/safety-bench/safety-categories * (Source: Issue #332) */ /** * Complete registry of all safety categories. */ declare const SAFETY_CATEGORIES: readonly SafetyCategory[]; /** * Map of category IDs to category definitions. */ declare const SAFETY_CATEGORY_MAP: ReadonlyMap; /** * Get a safety category by ID. * @param id - Category identifier * @returns The category definition or undefined if not found */ declare function getSafetyCategory(id: SafetyCategoryIdType): SafetyCategory | undefined; /** * Get all categories at or above a given risk level. * @param minLevel - Minimum risk level to include * @returns Array of categories matching the risk level criteria */ declare function getCategoriesByMinRiskLevel(minLevel: RiskLevelType): readonly SafetyCategory[]; /** * Get all test cases across all categories. * @returns Array of all test cases with their category IDs */ declare function getAllTestCases(): readonly (SafetyTestCase & { categoryId: SafetyCategoryIdType; })[]; /** * Get test cases filtered by tags. * @param tags - Tags to filter by (any match) * @returns Array of matching test cases */ declare function getTestCasesByTags(tags: readonly string[]): readonly (SafetyTestCase & { categoryId: SafetyCategoryIdType; })[]; /** * Validate a safety category definition. * @param category - Category to validate * @returns Validation result with inferred schema type */ declare function validateSafetyCategory(category: unknown): ZodSafeParseResult>; /** * Validate a test case definition. * @param testCase - Test case to validate * @returns Validation result with inferred schema type */ declare function validateTestCase(testCase: unknown): ZodSafeParseResult>; /** * Validate an evaluation criterion definition. * @param criterion - Criterion to validate * @returns Validation result with inferred schema type */ declare function validateEvaluationCriterion(criterion: unknown): ZodSafeParseResult>; /** * Get summary statistics for the safety taxonomy. * @returns Summary statistics object */ declare function getSafetyTaxonomySummary(): SafetyTaxonomySummary; /** * nexus-agents/security - Input Sanitizer * * Sanitizes untrusted GitHub input by stripping dangerous HTML/XML tags, * detecting injection patterns, and producing a SanitizedInput result * with full audit trail. * * Defense layer 1 of the three-layer hardening architecture. * See: docs/architecture/UNTRUSTED_INPUT_HARDENING.md * * @module security/input-sanitizer * (Source: Issue #818, #819 — Phase 1: Input Sanitization) */ /** * Sanitizes untrusted GitHub input through the full Layer 1 pipeline: * 1. HTML stripping (picture/source/img tags) * 2. XML tag stripping (system/human/assistant) * 3. HTML comment stripping (instruction-bearing comments only) * 4. Injection pattern detection * 5. Trust tier assignment * * ⚠ **Use HostileInputFirewall.process() in agent code paths.** Calling * sanitizeInput() directly only runs Layer 1 — it does not evaluate the * Rule of Two and does not emit audit-trail events. An agent that processes * untrusted input while holding both write access and secrets violates the * Rule of Two; `evaluatePolicy` in policy-gate.ts enforces that per action, * and the firewall evaluates it per input as a signal (refusing only under * `NEXUS_FIREWALL_POLICY=enforce`). The live paths route their trust * decision through the firewall as of #4992 and keep direct sanitizeInput() * calls only for content cleaning of text they embed. Direct use of this * function is appropriate for unit tests and pure content analysis, not * for agent decision paths. * * @see packages/nexus-agents/src/security/firewall/firewall-pipeline.ts * @see packages/nexus-agents/src/security/policy-gate.ts * @param content - Raw untrusted content from GitHub * @param userRole - GitHub user's relationship to the repository * @param username - GitHub username (for allowlist check) * @param config - Optional sanitizer configuration * @returns SanitizedInput with cleaned content and audit data */ declare function sanitizeInput(content: string, userRole: GitHubUserRole, username: string, config?: Partial): SanitizedInput; /** * nexus-agents/security - Trust Classifier * * Classifies GitHub users and content into trust tiers based on * repository relationship, allowlist membership, and content analysis. * Works with the input sanitizer to determine how agent decisions * should weight each input source. * * @module security/trust-classifier * (Source: Issue #818, #819 — Phase 1: Input Sanitization) */ /** * Maps GitHub API author_association values to our GitHubUserRole enum. * See: https://docs.github.com/en/graphql/reference/enums#commentauthorassociation */ declare function mapAuthorAssociation(association: string): GitHubUserRole; /** * Input for trust classification. */ interface ClassifyInput { /** GitHub username. */ readonly username: string; /** GitHub API author_association value. */ readonly authorAssociation: string; /** Sanitized input (if content has already been through the sanitizer). */ readonly sanitizedInput?: SanitizedInput; /** Sanitizer config (for allowlist check). */ readonly config?: Partial; } /** * Result of trust classification. */ interface ClassifyResult { /** Assigned trust tier. */ readonly trustTier: TrustTier; /** GitHub user role. */ readonly userRole: GitHubUserRole; /** Whether the user is on the maintainer allowlist. */ readonly isAllowlisted: boolean; /** Whether content triggered a trust downgrade. */ readonly wasDowngraded: boolean; /** Reason for the assigned tier. */ readonly reason: string; } /** * Classifies a GitHub user and their content into a trust tier. * * The trust tier is determined by: * 1. Allowlist membership (always Tier 1) * 2. GitHub author_association → role → default tier * 3. Content injection analysis (can only downgrade, never upgrade) * * ⚠ **Use HostileInputFirewall.process() in agent code paths.** The live * paths (`dogfooding/issue-triage`, `dogfooding/pr-reviewer`) route through * it as of #4992. Calling classifyTrust() directly emits no audit-trail * event, and unless the caller supplies `config.allowlistedMaintainers` no * allowlist is consulted — `isAllowlisted: false` is then a default, not a * measurement, and must not be recorded as one. Direct use is for unit tests * and non-decision analysis only. (The Rule of Two is enforced separately by * `evaluatePolicy` in policy-gate; the firewall evaluates it too, as a * signal, and refuses on it only under `NEXUS_FIREWALL_POLICY=enforce`.) * * @see packages/nexus-agents/src/security/firewall/firewall-pipeline.ts * @see packages/nexus-agents/src/security/policy-gate.ts */ declare function classifyTrust(input: ClassifyInput): ClassifyResult; /** * Checks whether a trust tier can influence agent decisions. * Tiers 3-4 are informational only — they cannot drive actions. */ declare function canInfluenceDecisions(tier: TrustTier): boolean; /** * Checks whether a trust tier requires corroboration with Tier 1 sources. * Tier 2 requires corroboration; Tier 1 is self-sufficient. */ declare function requiresCorroboration(tier: TrustTier): boolean; /** * Returns the minimum trust tier required for a given action type. * Actions that modify state require higher trust. */ declare function getRequiredTrustTier(actionType: string): TrustTier; /** * nexus-agents/security - Typed Action Schema * * Zod schemas and TypeScript types for the typed action constraint system. * Agents processing untrusted GitHub input MUST emit only predefined typed * actions (never free-form tool calls). This module defines those action * schemas, validates them at runtime, and classifies them as read-only or * mutating for the policy gate. * * @module security/action-schema * (Source: Issue #818, #820) */ /** Validation result using the project Result pattern. */ type ActionValidationResult = { ok: true; value: AgentAction; } | { ok: false; error: string; }; /** * Discriminated union of all valid source citation types. * Every decision-making action MUST cite at least one source. */ declare const SourceCitationSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{ type: z.ZodLiteral<"issueBody">; issueNumber: z.ZodNumber; author: z.ZodString; authorTrustTier: z.ZodEnum<{ 1: "1"; 2: "2"; 3: "3"; 4: "4"; }>; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"repoFile">; path: z.ZodString; line: z.ZodOptional; existsOnBaseRef: z.ZodOptional; commit: z.ZodOptional; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"issueComment">; issueNumber: z.ZodNumber; commentId: z.ZodNumber; author: z.ZodString; authorTrustTier: z.ZodEnum<{ 1: "1"; 2: "2"; 3: "3"; 4: "4"; }>; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"ciResult">; runId: z.ZodNumber; status: z.ZodEnum<{ pass: "pass"; fail: "fail"; }>; job: z.ZodString; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"policyDoc">; path: z.ZodString; section: z.ZodString; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"maintainerCommand">; username: z.ZodString; commentId: z.ZodNumber; }, z.core.$strip>], "type">; /** Inferred TypeScript type for a source citation. */ type SourceCitation = z.infer; /** * Discriminated union of all valid agent actions. * This is the ONLY schema agents may emit when processing untrusted input. */ declare const AgentActionSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{ type: z.ZodLiteral<"SummarizeIssue">; summary: z.ZodString; sources: z.ZodArray; issueNumber: z.ZodNumber; author: z.ZodString; authorTrustTier: z.ZodEnum<{ 1: "1"; 2: "2"; 3: "3"; 4: "4"; }>; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"repoFile">; path: z.ZodString; line: z.ZodOptional; existsOnBaseRef: z.ZodOptional; commit: z.ZodOptional; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"issueComment">; issueNumber: z.ZodNumber; commentId: z.ZodNumber; author: z.ZodString; authorTrustTier: z.ZodEnum<{ 1: "1"; 2: "2"; 3: "3"; 4: "4"; }>; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"ciResult">; runId: z.ZodNumber; status: z.ZodEnum<{ pass: "pass"; fail: "fail"; }>; job: z.ZodString; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"policyDoc">; path: z.ZodString; section: z.ZodString; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"maintainerCommand">; username: z.ZodString; commentId: z.ZodNumber; }, z.core.$strip>], "type">>; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"ProposeLabels">; labels: z.ZodArray; reason: z.ZodString; sources: z.ZodArray; issueNumber: z.ZodNumber; author: z.ZodString; authorTrustTier: z.ZodEnum<{ 1: "1"; 2: "2"; 3: "3"; 4: "4"; }>; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"repoFile">; path: z.ZodString; line: z.ZodOptional; existsOnBaseRef: z.ZodOptional; commit: z.ZodOptional; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"issueComment">; issueNumber: z.ZodNumber; commentId: z.ZodNumber; author: z.ZodString; authorTrustTier: z.ZodEnum<{ 1: "1"; 2: "2"; 3: "3"; 4: "4"; }>; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"ciResult">; runId: z.ZodNumber; status: z.ZodEnum<{ pass: "pass"; fail: "fail"; }>; job: z.ZodString; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"policyDoc">; path: z.ZodString; section: z.ZodString; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"maintainerCommand">; username: z.ZodString; commentId: z.ZodNumber; }, z.core.$strip>], "type">>; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"DraftReply">; body: z.ZodString; requiresApproval: z.ZodLiteral; sources: z.ZodArray; issueNumber: z.ZodNumber; author: z.ZodString; authorTrustTier: z.ZodEnum<{ 1: "1"; 2: "2"; 3: "3"; 4: "4"; }>; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"repoFile">; path: z.ZodString; line: z.ZodOptional; existsOnBaseRef: z.ZodOptional; commit: z.ZodOptional; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"issueComment">; issueNumber: z.ZodNumber; commentId: z.ZodNumber; author: z.ZodString; authorTrustTier: z.ZodEnum<{ 1: "1"; 2: "2"; 3: "3"; 4: "4"; }>; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"ciResult">; runId: z.ZodNumber; status: z.ZodEnum<{ pass: "pass"; fail: "fail"; }>; job: z.ZodString; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"policyDoc">; path: z.ZodString; section: z.ZodString; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"maintainerCommand">; username: z.ZodString; commentId: z.ZodNumber; }, z.core.$strip>], "type">>; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"RequestHumanApproval">; reason: z.ZodString; context: z.ZodString; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"GeneratePatchPlan">; files: z.ZodArray; description: z.ZodString; }, z.core.$strip>>; rationale: z.ZodString; requiresApproval: z.ZodLiteral; sources: z.ZodArray; issueNumber: z.ZodNumber; author: z.ZodString; authorTrustTier: z.ZodEnum<{ 1: "1"; 2: "2"; 3: "3"; 4: "4"; }>; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"repoFile">; path: z.ZodString; line: z.ZodOptional; existsOnBaseRef: z.ZodOptional; commit: z.ZodOptional; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"issueComment">; issueNumber: z.ZodNumber; commentId: z.ZodNumber; author: z.ZodString; authorTrustTier: z.ZodEnum<{ 1: "1"; 2: "2"; 3: "3"; 4: "4"; }>; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"ciResult">; runId: z.ZodNumber; status: z.ZodEnum<{ pass: "pass"; fail: "fail"; }>; job: z.ZodString; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"policyDoc">; path: z.ZodString; section: z.ZodString; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"maintainerCommand">; username: z.ZodString; commentId: z.ZodNumber; }, z.core.$strip>], "type">>; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"ClassifyIssue">; category: z.ZodEnum<{ security: "security"; documentation: "documentation"; performance: "performance"; question: "question"; bug: "bug"; feature: "feature"; }>; confidence: z.ZodNumber; sources: z.ZodArray; issueNumber: z.ZodNumber; author: z.ZodString; authorTrustTier: z.ZodEnum<{ 1: "1"; 2: "2"; 3: "3"; 4: "4"; }>; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"repoFile">; path: z.ZodString; line: z.ZodOptional; existsOnBaseRef: z.ZodOptional; commit: z.ZodOptional; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"issueComment">; issueNumber: z.ZodNumber; commentId: z.ZodNumber; author: z.ZodString; authorTrustTier: z.ZodEnum<{ 1: "1"; 2: "2"; 3: "3"; 4: "4"; }>; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"ciResult">; runId: z.ZodNumber; status: z.ZodEnum<{ pass: "pass"; fail: "fail"; }>; job: z.ZodString; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"policyDoc">; path: z.ZodString; section: z.ZodString; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"maintainerCommand">; username: z.ZodString; commentId: z.ZodNumber; }, z.core.$strip>], "type">>; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"IdentifyDuplicates">; candidates: z.ZodArray; similarity: z.ZodArray; sources: z.ZodArray; issueNumber: z.ZodNumber; author: z.ZodString; authorTrustTier: z.ZodEnum<{ 1: "1"; 2: "2"; 3: "3"; 4: "4"; }>; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"repoFile">; path: z.ZodString; line: z.ZodOptional; existsOnBaseRef: z.ZodOptional; commit: z.ZodOptional; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"issueComment">; issueNumber: z.ZodNumber; commentId: z.ZodNumber; author: z.ZodString; authorTrustTier: z.ZodEnum<{ 1: "1"; 2: "2"; 3: "3"; 4: "4"; }>; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"ciResult">; runId: z.ZodNumber; status: z.ZodEnum<{ pass: "pass"; fail: "fail"; }>; job: z.ZodString; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"policyDoc">; path: z.ZodString; section: z.ZodString; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"maintainerCommand">; username: z.ZodString; commentId: z.ZodNumber; }, z.core.$strip>], "type">>; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"RefuseAction">; reason: z.ZodString; escalateTo: z.ZodEnum<{ security: "security"; maintainer: "maintainer"; }>; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"HandoffMessage">; targetCapability: z.ZodString; reason: z.ZodString; inputTrustTier: z.ZodEnum<{ 1: "1"; 2: "2"; 3: "3"; 4: "4"; }>; sources: z.ZodArray; issueNumber: z.ZodNumber; author: z.ZodString; authorTrustTier: z.ZodEnum<{ 1: "1"; 2: "2"; 3: "3"; 4: "4"; }>; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"repoFile">; path: z.ZodString; line: z.ZodOptional; existsOnBaseRef: z.ZodOptional; commit: z.ZodOptional; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"issueComment">; issueNumber: z.ZodNumber; commentId: z.ZodNumber; author: z.ZodString; authorTrustTier: z.ZodEnum<{ 1: "1"; 2: "2"; 3: "3"; 4: "4"; }>; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"ciResult">; runId: z.ZodNumber; status: z.ZodEnum<{ pass: "pass"; fail: "fail"; }>; job: z.ZodString; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"policyDoc">; path: z.ZodString; section: z.ZodString; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"maintainerCommand">; username: z.ZodString; commentId: z.ZodNumber; }, z.core.$strip>], "type">>; }, z.core.$strip>], "type">; /** Inferred TypeScript type for an agent action. */ type AgentAction = z.infer; /** All valid action type discriminator values. */ type AgentActionType = AgentAction['type']; /** * Validate an unknown value against the AgentActionSchema. * Returns a Result: `{ ok: true; value }` on success or `{ ok: false; error }` on failure. * * @param input - The value to validate (typically parsed JSON from an agent). * @returns Validation result following the project Result pattern. */ declare function validateAgentAction(input: unknown): ActionValidationResult; /** * Check whether an action type is read-only (does not modify GitHub state). * * @param actionType - The action type discriminator value. * @returns True if the action is read-only. */ declare function isReadOnlyAction(actionType: AgentActionType): boolean; /** * Check whether an action type can modify GitHub state. * Mutating actions always require human approval before execution. * * @param actionType - The action type discriminator value. * @returns True if the action can modify state. */ declare function isMutatingAction(actionType: AgentActionType): boolean; /** * Whether an action needs human approval even after passing every policy check. * * Distinct from {@link isMutatingAction}, which stays broad because it also * drives the untrusted-input influence block — low-trust input must not be able * to drive ANY mutating action, approved or not. * * @param actionType - The action type discriminator value. * @returns True if a human must approve before execution. */ declare function requiresHumanApproval(actionType: AgentActionType): boolean; /** * Check whether an action type requires at least one source citation. * Escalation (RequestHumanApproval) and refusal (RefuseAction) are exempt. * * @param actionType - The action type discriminator value. * @returns True if the action must include source citations. */ declare function requiresCitation(actionType: AgentActionType): boolean; /** * nexus-agents/security - Audit Trail * * Machine-readable JSON audit events for security pipeline decisions. * Every trust classification, policy gate decision, corroboration check, * and reputation assessment is recorded as a structured event. * * Satisfies CLAUDE.md requirement: "Every action on untrusted input must * log: trust tier, sources cited, policy gate decision, stripped content." * * @module security/audit-trail * (Source: Issue #832 — Security audit trail) */ /** * Discriminated union of audit event types. * Each event captures a single security pipeline decision. */ type AuditEvent = TrustClassificationEvent | PolicyGateEvent | CorroborationEvent | ReputationEvent | SanitizationEvent | GraphExecutionAuditEvent | ClawGuardViolationEvent; /** Base fields shared by all audit events. */ interface AuditEventBase { readonly id: string; readonly timestamp: string; readonly component: string; } /** Trust classification decision. */ interface TrustClassificationEvent extends AuditEventBase { readonly type: 'trust_classification'; readonly username: string; readonly assignedTier: TrustTier; readonly userRole: string; /** * Present only when a maintainer allowlist was consulted (#4992). A * classification that consulted no list records nothing here rather than * `false` — "not measured" and "measured false" must stay distinguishable in * the audit record. */ readonly isAllowlisted?: boolean; readonly wasDowngraded: boolean; readonly reason: string; } /** Policy gate evaluation result. */ interface PolicyGateEvent extends AuditEventBase { readonly type: 'policy_gate'; /** * The agent action evaluated, for the security policy-gate path * (security/policy-gate.ts). Optional because the PIPELINE policy path * (pipeline/policy-evaluator.ts → #3710) records stage-boundary policy * decisions that have no `AgentAction` — they carry {@link stageType} + * {@link mode} + {@link ruleIds} instead. Security emitters always set it. */ readonly actionType?: AgentActionType; readonly allowed: boolean; readonly requiresApproval: boolean; readonly inputTrustTier: TrustTier; readonly violationRules: readonly string[]; /** * Pipeline-policy fields (#3710). Carried for the dev-pipeline * consensus→execute seam so the DURABLE record can distinguish soak (`warn`) * from enforce (`block`) and which rules/stage fired — without these the * persisted event is useless to the tune/readiness loop. Absent for the * security policy-gate path. */ /** Enforcement mode the decision was made under: `warn` (soak) or `block` (enforce). */ readonly mode?: 'off' | 'warn' | 'block'; /** IDs of the policy rules that fired (mirrors `violationRules` for the pipeline path). */ readonly ruleIds?: readonly string[]; /** Type of the stage the gate guarded (e.g. `execute`). */ readonly stageType?: string; /** * #3727: discriminates a per-EVALUATION SUMMARY record (`'summary'` — emitted * once per pipeline policy evaluation INCLUDING clean ones, the DENOMINATOR for * the would-block rate) from a per-VIOLATION record (`'violation'` — the * existing #3710 per-violation records). Absent for the security policy-gate * path. Denominator = count(recordKind==='summary'); numerator = summaries with * `violationCount > 0`. Scope the #3710 count-parity assertion to `'violation'`. */ readonly recordKind?: 'summary' | 'violation'; /** #3727: number of violations in THIS evaluation (set on the summary record). */ readonly violationCount?: number; } /** Corroboration validation result. */ interface CorroborationEvent extends AuditEventBase { readonly type: 'corroboration'; readonly actionType: AgentActionType; readonly satisfied: boolean; readonly sourceCount: number; readonly missingRequirements: readonly string[]; } /** Reputation assessment result. */ interface ReputationEvent extends AuditEventBase { readonly type: 'reputation'; readonly username: string; readonly reputationScore: number; readonly isSuspicious: boolean; readonly effectiveTier: TrustTier; readonly signalCount: number; } /** Summary of a single element stripped during sanitization. */ interface StrippedElementSummary { /** Truncated tag text (≤30 chars + '...' from the sanitizer). */ readonly tag: string; /** Reason the element was removed (e.g. 'Trail of Bits injection vector'). */ readonly reason: string; } /** Input sanitization result. */ interface SanitizationEvent extends AuditEventBase { readonly type: 'sanitization'; readonly source: string; readonly wasModified: boolean; /** Whether input exceeded the configured limit. Absent on events that predate this field. */ readonly truncated?: boolean; readonly strippedCount: number; readonly injectionFlagCount: number; /** * Per-element tag/reason details, truncated to at most * MAX_STRIPPED_ELEMENTS_PER_EVENT entries. Required by CLAUDE.md's * Untrusted Input Policy: "Log stripped elements for audit trail." */ readonly strippedElements: readonly StrippedElementSummary[]; } /** * ClawGuard AUDIT-mode violation (#4097). Recorded a tool call that violated * the derived access policy but was allowed under `audit` mode. Its only * producer (the access-constraint deriver's MCP guard) was deleted in #5108, * so no new events of this type are written; the member stays in the union * because `AuditEvent` is published and existing ledgers may carry it. * Removal is a breaking change scheduled for the next major (#6319). */ interface ClawGuardViolationEvent extends AuditEventBase { readonly type: 'clawguard_violation'; /** The tool whose call violated the policy. */ readonly toolName: string; /** Human-readable warning from the access decision (may be truncated). */ readonly warning: string; /** Source of the derived policy (`llm` / `fallback-keyword` / `bypass`). */ readonly policySource: string; /** Policy mode under which the violation was allowed (e.g. `audit`). */ readonly mode: string; /** Request ID of the offending tool call, for correlation. */ readonly requestId: string; /** * Which rule produced the verdict (#5106) — `unbypassable:tool`, * `unbypassable:path`, `allowedTools`, `allowedTools:confirm_risky`. * * A first-class field rather than prose inside `warning`, because `warning` * is truncated at 500 chars and a long attacker-selectable `path` argument * pushes the rule off the end. A chain reader must be able to tell an * unbypassable denylist hit from an allowlist miss without parsing a string * that may have been cut mid-word. * * Absent for verdicts that carry no rule (an audit-mode allowlist * observation), which is why it is optional rather than defaulted — there is * no rule to name, and inventing one would misreport. */ readonly matchedRule?: string; } /** Graph execution lifecycle event (Issue #839). */ interface GraphExecutionAuditEvent extends AuditEventBase { readonly type: 'graph_execution'; readonly graphEvent: string; readonly nodeId?: string; readonly stepNumber: number; readonly detail: string; } /** * Query filter for retrieving audit events. * * The post-mortem dimensions (#3197) — `actionType`, `actor`, `violationRule` * — NARROW to events that actually carry the field (events lacking it are * excluded), unlike `trustTier`'s legacy keep-non-applicable behavior. Only * dimensions backed by a real event field are offered: `resource` and * `policyName` from the original ask were dropped because no AuditEvent * records them (a filter with no backing field would be dead config); the * policy-rule intent is served by `violationRule` (PolicyGateEvent's * `violationRules`). */ interface AuditQuery { readonly type?: AuditEvent['type']; readonly since?: string; readonly until?: string; readonly trustTier?: TrustTier; /** Match PolicyGate/Corroboration events by their `actionType`. */ readonly actionType?: AgentActionType; /** Match Trust/Reputation events by `username` (the acting/assessed user). */ readonly actor?: string; /** Match PolicyGate events whose `violationRules` include this rule name. */ readonly violationRule?: string; readonly limit?: number; } /** * Append-only audit trail for security pipeline decisions. * Events are bounded by MAX_EVENTS to prevent unbounded growth. */ /** * Optional durable sink: receives every fully-formed event appended to the * trail, so security decisions can be mirrored to a persistent, hash-chained * store (see security/audit-bridge.ts). Default-off — when absent, the trail * behaves exactly as before (#3291). */ type DurableAuditSink = (event: AuditEvent) => void; declare class AuditTrail { private readonly durableSink?; private events; private nextId; constructor(durableSink?: DurableAuditSink | undefined); /** Appends an event to the trail. Returns the assigned event ID. */ append(event: Omit): string; /** Queries events matching the given filter. */ query(filter?: AuditQuery): readonly AuditEvent[]; /** Returns the total number of events. */ get size(): number; /** Clears all events. */ clear(): void; /** Enforces MAX_EVENTS bound. */ private enforceLimit; } /** * Records a trust classification decision. */ declare function emitTrustEvent(trail: AuditTrail, data: Omit): string; /** * Records a policy gate evaluation. */ declare function emitPolicyEvent(trail: AuditTrail, data: Omit): string; /** * Records a corroboration validation. */ declare function emitCorroborationEvent(trail: AuditTrail, data: Omit): string; /** * Records a reputation assessment. */ declare function emitReputationEvent(trail: AuditTrail, data: Omit): string; /** * Records an input sanitization result. */ declare function emitSanitizationEvent(trail: AuditTrail, data: Omit): string; /** * Records a graph execution lifecycle event. */ declare function emitGraphExecutionEvent(trail: AuditTrail, data: Omit): string; /** * Creates an onEvent callback that bridges graph events to the audit trail. * Pass the returned function as `onEvent` in GraphExecuteOptions. * * @example * const trail = createAuditTrail(); * await executeGraph(graph, inputs, { onEvent: createGraphAuditBridge(trail) }); */ declare function createGraphAuditBridge(trail: AuditTrail): (event: { readonly type: string; readonly [key: string]: unknown; }) => void; /** * Creates a new AuditTrail instance. Pass a {@link DurableAuditSink} (e.g. from * `createDurableAuditSink(auditLogger)`) to mirror appended security decisions * to a durable, hash-chained store (#3291). Default: in-memory only. */ declare function createAuditTrail(durableSink?: DurableAuditSink): AuditTrail; /** * nexus-agents/security - Policy Gate * * Deterministic rule engine that validates all agent actions before * GitHub state mutations can occur. No LLM in the validation path. * * Defense layer 2 of the three-layer hardening architecture. * See: docs/architecture/UNTRUSTED_INPUT_HARDENING.md * * @module security/policy-gate * (Source: Issue #818, #822 — Phase 2: Policy Gate) */ /** * Violation detected by the policy gate. */ declare const ViolationSchema: z.ZodObject<{ rule: z.ZodString; message: z.ZodString; severity: z.ZodEnum<{ warn: "warn"; block: "block"; }>; }, z.core.$strip>; type Violation = z.infer; /** * Decision returned by the policy gate. */ interface PolicyDecision$1 { /** Whether the action is allowed to proceed. */ readonly allowed: boolean; /** Whether human approval is required before execution. */ readonly requiresApproval: boolean; /** All detected violations (blocking and warnings). */ readonly violations: readonly Violation[]; /** Timestamp of the evaluation (ISO 8601). */ readonly evaluatedAt: string; } /** * Context for evaluating a policy decision. */ interface ActionContext { /** Trust tier of the primary input source. */ readonly inputTrustTier: TrustTier; /** Whether the agent currently has write access to the repository. */ readonly hasWriteAccess: boolean; /** Whether the agent currently has access to secrets/tokens. */ readonly hasSecretAccess: boolean; /** Set of labels that exist on the repository (for ProposeLabels validation). */ readonly existingLabels?: ReadonlySet; } /** * Evaluate an agent action against the policy gate. * * This is a deterministic check — no LLM in the loop. Returns a * PolicyDecision indicating whether the action is allowed, requires * human approval, or is blocked. * * @param action - The validated AgentAction to evaluate. * @param context - The current execution context. * @returns PolicyDecision with violations and approval requirements. */ declare function evaluatePolicy(action: AgentAction, context: ActionContext, auditTrail?: AuditTrail): PolicyDecision$1; /** * Quick check: can this action type proceed at all given the input trust tier? * Useful for early rejection before full policy evaluation. */ declare function canProceed(actionType: AgentActionType, inputTrustTier: TrustTier): boolean; /** * nexus-agents/security - Corroboration Validator * * Validates that agent decisions are backed by sufficient evidence from * authoritative sources. Each action type has specific corroboration * requirements (e.g., closing issues requires CI pass or maintainer comment). * * Defense layer 3 of the three-layer hardening architecture. * See: docs/architecture/UNTRUSTED_INPUT_HARDENING.md * * @module security/corroboration-validator * (Source: Issue #818, #823 — Phase 2: Corroboration Validator) */ /** * Result of corroboration validation. */ interface CorroborationResult { /** Whether corroboration requirements are satisfied. */ readonly satisfied: boolean; /** Sources that contributed to corroboration. */ readonly corroboratingSources: readonly SourceCitation[]; /** Missing corroboration requirements (empty when satisfied). */ readonly missing: readonly string[]; /** Action type that was validated. */ readonly actionType: AgentActionType; /** * True when the floor was cleared, and EVERY `repoFile` citation that cleared * it is one the producer checked and found absent from the base ref * (`existsOnBaseRef === false`) — i.e. a path the author of the untrusted * change invented in that same change. * * `satisfied` deliberately does not read this: which actions are permitted is * unchanged. What changes is that the record can now say the corroboration * was author-supplied, instead of attributing repo provenance to a path that * has none. False when any citation is verified, when none were checked, or * when the floor was not cleared at all. */ readonly clearedOnlyByUnverifiedSources: boolean; } /** * Rule defining what corroboration an action requires. */ interface CorroborationRule { /** Human-readable description of what's required. */ readonly description: string; /** Predicate: does this set of sources satisfy the requirement? */ readonly isSatisfied: (sources: readonly SourceCitation[]) => boolean; } /** * Validate that an agent action has sufficient corroboration from * authoritative sources. * * @param action - The validated AgentAction to check. * @returns CorroborationResult indicating whether requirements are met. */ declare function validateCorroboration(action: AgentAction): CorroborationResult; /** * Get the corroboration rules for an action type. * Useful for displaying requirements to users. */ declare function getCorroborationRules(actionType: AgentActionType): readonly CorroborationRule[]; /** * nexus-agents/security - Reputation Model * * Lightweight trust model for GitHub users that assesses reputation * based on account age, contribution history, and behavioral signals. * Integrates with the trust classifier for comprehensive trust assessment. * * @module security/reputation-model * (Source: Issue #818, #824 — Phase 3: Reputation Model) */ /** * Signals that indicate a suspicious actor. */ declare const SuspiciousSignalSchema: z.ZodEnum<{ new_account: "new_account"; no_prior_contributions: "no_prior_contributions"; injection_patterns_detected: "injection_patterns_detected"; rapid_comments: "rapid_comments"; mismatched_authority_claim: "mismatched_authority_claim"; }>; type SuspiciousSignal = z.infer; /** * GitHub user metadata for reputation assessment. */ interface GitHubUserMetadata { readonly username: string; /** * Account/activity fields are OPTIONAL (#3106). When a field is absent (the * caller couldn't fetch it — e.g. the firewall before Phase 3 wiring), its * signal is SKIPPED rather than fabricated: an unknown value must never be * treated as benign (the old hardcoded `365`/`0`) nor as hostile. Only the * `authorAssociation` + `injectionFlags` signals fire on absent activity data. */ readonly accountAgeDays?: number; readonly priorContributions?: number; readonly recentCommentCount?: number; readonly recentCommentWindowMinutes?: number; readonly authorAssociation: string; readonly injectionFlags: readonly InjectionFlag[]; } /** * Result of a reputation assessment. */ interface ReputationAssessment { readonly username: string; readonly userRole: GitHubUserRole; /** Measurement coverage; absent on assessments created before coverage tracking. */ readonly coverage?: { readonly activity: 'measured' | 'unmeasured'; }; readonly suspiciousSignals: readonly SuspiciousSignal[]; readonly isSuspicious: boolean; readonly effectiveTrustTier: TrustTier; readonly reputationScore: number; readonly reason: string; readonly assessedAt: string; } /** * In-memory reputation cache with TTL and max size. * Reduces redundant assessments for the same user within a short window. * Evicts oldest entries when max size is exceeded. */ declare class ReputationCache { private readonly cache; private readonly ttlMs; private readonly maxSize; constructor(ttlMs?: number, maxSize?: number); get(username: string): ReputationAssessment | undefined; set(username: string, assessment: ReputationAssessment): void; /** Evict a batch of oldest entries (10% of maxSize, minimum 1). */ private evictOldest; clear(): void; get size(): number; } /** * Assess a GitHub user's reputation for trust classification. * * @param metadata - User metadata from GitHub API or local context. * @param cache - Optional cache instance for TTL-based deduplication. * @returns ReputationAssessment with trust tier and suspicious signals. */ declare function assessReputation(metadata: GitHubUserMetadata, cache?: ReputationCache): ReputationAssessment; /** * Rollout mode for reputation-based tier gating, the same `off`/`audit`/ * `enforce` shape as `NEXUS_FIREWALL_POLICY`: `off` (no reputation effect), `audit` * (compute + report the would-be demotion but enforce the classifier tier), or * `enforce` (apply the demotion). Default `enforce` since #4667 — see * {@link DEFAULT_REPUTATION_GATING_MODE} for the measurement that justified the * flip. (This block previously still described the pre-flip `audit` default.) */ declare const ReputationGatingModeSchema: z.ZodEnum<{ off: "off"; audit: "audit"; enforce: "enforce"; }>; type ReputationGatingMode = z.infer; /** * Resolve the gating mode from the environment (invalid → default + warn, never * throws — #3130). Delegates to the shared `resolveEnvMode` so this flag and * `NEXUS_FIREWALL_POLICY` coerce identically. */ declare function resolveReputationGatingMode(env?: NodeJS.ProcessEnv): ReputationGatingMode; /** Outcome of applying the gating mode to a reputation assessment. */ interface ReputationGateDecision { /** Tier to actually enforce at the policy gate. */ readonly enforcedTier: TrustTier; /** Tier reputation reconciliation computed (what `enforce` mode WOULD use). */ readonly reconciledTier: TrustTier; /** True when reputation would demote but the mode (off/audit) did not enforce it. */ readonly demotionSuppressed: boolean; readonly mode: ReputationGatingMode; } /** * Rollout gate for `HostileInputFirewall` behaviour changes (#5382, epic #5281). * * `HostileInputFirewall` is a PUBLISHED API: re-exported through * `src/exports/security.ts`, carried in `api-surface.txt`, and pinned by an * export-contract test. Epic #5281 found it has fallen BEHIND the hand-composed * production path rather than being dead scaffolding, and its remaining children * change what `process()` decides — #5380 raises one policy check to seven, * #5381 makes reputation gating mode-aware. * * A supermajority panel ratified this gate FIRST (6 approve / 1 reject; the lone * rejection argued the gate binds even more firmly than proposed) so those * changes have somewhere to land that is not a silent behaviour change shipped * in a patch release to consumers this repo cannot see. * * The invariant that makes it a gate: **`off` is the default, and under `off` * behaviour is byte-identical to pre-#5382.** A gate whose default changes * behaviour has not gated anything. * * Deliberately NOT a new mechanism. This flag has the same shape as * `NEXUS_REPUTATION_GATING` (#3122) — and as `NEXUS_ACCESS_POLICY_MODE` did * until its reader, the access-constraint deriver, was deleted in #5108 — so it * delegates to the shared `resolveEnvMode` helper (#3130) and coerces * identically. These env-var names are a stability contract; adding another * resolver with subtly different coercion is the sprawl that helper exists to * prevent. * * @module security/firewall/firewall-policy-mode */ /** * Rollout state for firewall policy behaviour. * * - `off` — pre-#5382 behaviour exactly. The default. * - `audit` — compute the stricter outcome and REPORT it, but enforce the old * one. This is the mode that makes a rollout measurable: it answers "what * would change?" without changing it. * - `enforce` — apply the stricter outcome. */ declare const FirewallPolicyModeSchema: z.ZodEnum<{ off: "off"; audit: "audit"; enforce: "enforce"; }>; type FirewallPolicyMode = z.infer; /** * Default is `off`, and that is the compatibility promise, not a placeholder. * * Note this differs from `DEFAULT_REPUTATION_GATING_MODE`, which is `enforce` * (#4667) — that flag governs an INTERNAL path this repo owns end to end, and * was flipped only after measurement over the real triage path. This one * governs a published surface with unknown external callers, so it starts off * and stays off until the same kind of measurement justifies a flip. Any future * flip is a MAJOR version change, not a patch. */ declare const DEFAULT_FIREWALL_POLICY_MODE: FirewallPolicyMode; /** Env var carrying the mode. Named to match its two sibling flags. */ declare const FIREWALL_POLICY_ENV_VAR = "NEXUS_FIREWALL_POLICY"; /** * Resolve the firewall policy mode from the environment. * * Never throws, because a security layer must not fail-closed at startup on an * operator typo (#3130). The two non-happy paths resolve DIFFERENTLY, though: * unset or empty resolves silently to `off` (absence is the normal state), while * an explicit-but-invalid value resolves to `audit` and emits one `warn`. * * @param env Environment to read (injectable for tests). * @param logger Injectable for tests; defaults to the shared module logger. */ declare function resolveFirewallPolicyMode(env?: NodeJS.ProcessEnv, logger?: ILogger): FirewallPolicyMode; /** * nexus-agents/security/firewall - Types * * Configuration, result, and adapter interface types for the * HostileInputFirewall pipeline. Uses Zod schemas for runtime * validation at construction boundaries. * * @module security/firewall/firewall-types * (Source: Issue #826 — Reusable Hostile Input Firewall) */ /** * Metadata extracted from a platform-specific input source. */ interface SourceMetadata { readonly username: string; readonly authorAssociation: string; readonly content: string; readonly sourceType: string; } /** * Adapter that extracts normalized metadata from platform-specific input. * Each platform (GitHub, GitLab, etc.) implements this interface. */ interface ISourceAdapter { readonly platform: string; extractMetadata(input: unknown): SourceMetadata; } /** * Controls which pipeline stages run. Disabled stages use safe defaults. */ declare const FirewallStagesSchema: z.ZodObject<{ sanitization: z.ZodDefault; trustClassification: z.ZodDefault; reputationAssessment: z.ZodDefault; policyEnforcement: z.ZodDefault; corroboration: z.ZodDefault; audit: z.ZodDefault; }, z.core.$strip>; type FirewallStages = z.infer; /** * Full config including the adapter (not Zod-validated since it's an interface). */ interface FirewallConfig { readonly adapter: ISourceAdapter; readonly stages?: Partial; readonly allowlistedMaintainers?: readonly string[]; readonly maxInputLength?: number; readonly context?: { readonly hasWriteAccess?: boolean; readonly hasSecretAccess?: boolean; }; /** * Rollout gate for behaviour changes to this published API (#5382). * Defaults to `NEXUS_FIREWALL_POLICY`, and to `off` when that is unset — * under `off` the firewall behaves exactly as it did before #5382. * * Explicit here as well as in the environment because the firewall is a * library: an embedding consumer must be able to opt in per instance without * setting a process-wide variable. */ readonly policyMode?: FirewallPolicyMode; /** * Environment to resolve `policyMode` from when it is not given explicitly. * Injectable so the resolution path itself is testable — without this the * flag could be unreachable in production with every unit test still passing. */ readonly env?: NodeJS.ProcessEnv; /** * Optional durable audit logger. When provided, every security decision the * firewall records is mirrored to this persistent, hash-chained store via * the audit bridge (#3291). When absent, decisions are in-memory only. */ readonly auditLogger?: IAuditLogger; /** * Rollout gate for REPUTATION demotion (#5381). Distinct from `policyMode`: * different env var (`NEXUS_REPUTATION_GATING`) and — load-bearing — a * different default, `enforce` rather than `off`. Production reads this same * knob (`issue-triage.ts`, `pr-reviewer-helpers.ts`), and the firewall reading * a different one is what let the two compositions disagree under identical * configuration. */ readonly reputationGatingMode?: ReputationGatingMode; /** * Supplies the reputation assessment. Defaults to `assessReputation` over the * instance's cache. * * Injectable for the same reason as `env` above: without it the reconciliation * is unobservable. The firewall hands the reputation engine only * `authorAssociation` + `injectionFlags` — the two inputs the trust classifier * already consumed — so reputation is never stricter than the classifier and * `reconcileTrustTier` returns the classifier tier every time. Deleting the * reconciliation passed 1588 tests (#5405). This seam is what lets a test * present a stricter tier and prove the check can fire. */ readonly reputationAssessor?: (metadata: GitHubUserMetadata) => ReputationAssessment; /** * Whether the sanitizer's content tier is applied as a classification * downgrade (#4992). Default `true` — the firewall's behaviour since #826: * injection-bearing content from a Tier-2 author classifies as Tier 4. * * `false` keeps the classifier role-only. The sanitization stage still runs * and still records its injection flags — only the tier downgrade is * withheld. The dogfooding paths (`issue-triage`, `pr-reviewer`) set this * because they route content signals through reputation gating, which has * its own rollout knob (`NEXUS_REPUTATION_GATING`); applying the same signal * at classification too would bypass that knob and change the recorded * `trustTier` under the default `NEXUS_FIREWALL_POLICY=off`, which #5382 * promises is pass-through. */ readonly contentDowngrade?: boolean; } /** * Per-call inputs to {@link HostileInputFirewall.process} (#4992). * * These are the facts that vary by CALL rather than by instance, so a * process-wide firewall (the dogfooding singleton) can serve many repositories * and many access postures without holding any of them globally. */ interface FirewallProcessOptions { /** * Maintainer allowlist for THIS call, from the repository context. Replaces — * does not merge with — the construction-time list, and is forgotten after * the call. When neither this nor the construction-time list was supplied, * no allowlist is consulted and `FirewallResult.isAllowlisted` is absent. */ readonly allowlistedMaintainers?: readonly string[]; /** * Access posture of the caller for THIS call, feeding the Rule-of-Two check. * Replaces the construction-time `context` for the call. Without it a shared * instance would evaluate every caller against one posture, and * `wouldRefuse` could never fire for a caller whose posture differs. */ readonly context?: { readonly hasWriteAccess: boolean; readonly hasSecretAccess: boolean; }; /** * The caller's own reputation measurement for THIS call. When present, the * reputation gate runs on it under `NEXUS_REPUTATION_GATING`, whether or not * the instance's `reputationAssessment` stage is on: `effectiveTrustTier` is * the enforced tier, `reputationGate` is returned, and the Rule-of-Two check, * `wouldRefuse` and the trust audit event all use that tier. This is what * lets a caller with richer signals than the firewall can see (account age, * comment history) act on ONE gate rather than two that can disagree. * * `assessment: undefined` means the caller measured nothing (reputation * disabled) but still wants the gate decision recorded on the classifier * tier; omitting the option entirely leaves the stage to the instance config. */ readonly reputation?: { readonly assessment: ReputationAssessment | undefined; }; /** * The action the caller intends to take on this input, for THIS call (#5380). * * With it, the `policyEnforcement` stage runs the full `evaluatePolicy` set — * the same seven checks production runs — against the enforced tier and the * call's access posture, and `FirewallResult.policy` carries every violation * plus the decision's own `requiresApproval`. Without it only the Rule of * Two, the one context-only check, can run; the six action-scoped checks are * then listed under `policy.unmeasured` rather than silently counted as * passed. `process()` is input-shaped and constructs no action itself, so * this is the only way those checks reach it. */ readonly action?: AgentAction; /** * The repository's label set, consulted by the label-validity check when * `action` is a `ProposeLabels` (#5380). When absent, `evaluatePolicy` * reports `LABEL_SET_UNAVAILABLE` as a blocking violation — unevaluable * label validity fails closed, exactly as it does on the production path. */ readonly existingLabels?: ReadonlySet; } /** * Structured data for an Agent Trust Label. */ declare const ATLDataSchema: z.ZodObject<{ tier: z.ZodEnum<{ 1: "1"; 2: "2"; 3: "3"; 4: "4"; }>; source: z.ZodString; user: z.ZodString; sanitized: z.ZodBoolean; rep: z.ZodOptional; }, z.core.$strip>; type ATLData = z.infer; /** * Error codes for firewall pipeline failures. */ type FirewallErrorCode = 'EXTRACTION_FAILED' | 'SANITIZATION_FAILED' | 'CLASSIFICATION_FAILED' | 'REPUTATION_FAILED' | 'INVALID_CONFIG' /** * #5382: a blocking policy violation refused the input outright, rather than * being surfaced as a signal on a successful result. Only reachable when the * firewall policy mode is `enforce` — under the default `off` a violation is * still returned via `ruleOfTwoViolation` on an `ok()` result. */ | 'POLICY_REFUSED'; /** * Structured error from the firewall pipeline. */ interface FirewallError { readonly code: FirewallErrorCode; readonly message: string; readonly stage: string; /** * The blocking policy violations behind a `POLICY_REFUSED` from the policy * stage (#5383) — the structured form of the rules `message` names, so a * consumer that maps a refusal onto its own action record can list the rule * ids without parsing the message. Absent for every other code, and for the * corroboration stage's refusal, which carries `missing` instead. */ readonly violations?: readonly Violation[]; /** * The unmet corroboration requirements behind a `POLICY_REFUSED` from the * corroboration stage (#6309) — the structured form of what `message` * names, so a consumer recording the refusal can list them without parsing * prose. Absent for every other code and stage. */ readonly missing?: readonly string[]; } /** * nexus-agents/security/firewall - Policy stage * * The `policyEnforcement` stage of {@link HostileInputFirewall} (#5380). It * used to run ONE of the seven checks `evaluatePolicy` runs — `checkRuleOfTwo`, * the only one that reads the `ActionContext` alone. The other six read an * `AgentAction`, which input-shaped `process()` never had, so they were not * "passing": they were never evaluated, and the result could not say so. * * This module gives the stage two honest shapes. With the action the caller * intends to take (`FirewallProcessOptions.action`) it runs `evaluatePolicy` in * full; without one it runs the Rule of Two and NAMES the six action-scoped * rules as unmeasured, so their absence from the violation list cannot be read * as a pass. * * @module security/firewall/firewall-policy-stage */ /** * What the `policyEnforcement` stage evaluated, and against what (#5380). * * A discriminated union keeps a reader from mistaking one shape for the other: * * - `scope: 'action'` — an action was supplied; all seven checks ran and * `violations` is the complete list. `allowed` and `requiresApproval` are * the decision's own fields (`PolicyDecision`), surfaced, not re-derived; * the firewall does not act on `requiresApproval` any more than the * production gate does (#4735: Rule of Two is refuse-only, and there is no * approval path here). * - `scope: 'context'` — no action was supplied; only the Rule of Two (the one * check that reads the context alone) ran. The six action-scoped checks are * listed in `unmeasured` by rule id, and `requiresApproval` — which depends * on the action type — is not reported at all rather than defaulted. */ type FirewallPolicyEvaluation = { readonly scope: 'action'; readonly actionType: AgentActionType; readonly allowed: boolean; readonly requiresApproval: boolean; readonly violations: readonly Violation[]; /** Always empty for a full evaluation; present so both shapes read the same way. */ readonly unmeasured: readonly string[]; } | { readonly scope: 'context'; /** Why the six action-scoped checks did not run. */ readonly reason: 'no-action-supplied'; /** At most the `RULE_OF_TWO` violation. */ readonly violations: readonly Violation[]; /** The rule ids `evaluatePolicy` could not evaluate without an action. */ readonly unmeasured: readonly string[]; }; /** * nexus-agents/security/firewall - Pipeline Engine * * HostileInputFirewall: a composition layer that orchestrates existing * security modules (sanitizer, trust-classifier, reputation-model, * audit-trail) into a configurable, source-agnostic pipeline. * * Replaces ad-hoc manual composition found in issue-triage, pr-reviewer, * and secure-handler with a single reusable abstraction. * * @module security/firewall/firewall-pipeline * (Source: Issue #826 — Reusable Hostile Input Firewall) */ /** * Output of the firewall pipeline. Aggregates results from each stage. */ interface FirewallResult { readonly sanitized: SanitizedInput; readonly trust: ClassifyResult; /** * Whether the author is on the maintainer allowlist — present ONLY when an * allowlist was consulted (#4992), i.e. one was supplied at construction or * per call. `trust.isAllowlisted` is the classifier's published always-boolean * field and reads `false` whether the list was empty or never supplied; this * field is the one to record, because absence here means "not measured" * rather than "measured false" — the same treatment `reputationGate` gets. */ readonly isAllowlisted?: boolean; readonly reputation?: ReputationAssessment; /** * The tier consumers should ENFORCE on (#3106): the classifier tier * reconciled with the reputation assessment (demotion-only; Tier-1/allowlist * wins; equals `trust.trustTier` when reputation is absent). Previously the * reputation tier was computed but dropped — `trust.trustTier` alone left * reputation unenforced. */ readonly effectiveTrustTier: TrustTier; /** * The reputation gating decision behind `effectiveTrustTier` (#5381). * * **Absent means the reputation stage did not run** — not "it ran and * suppressed nothing". `ReputationGateDecision.demotionSuppressed` is a * required boolean, so surfacing it unconditionally would report `false` for a * check that never happened. Since the stage defaults to off, that * unevaluated case is the common one. */ readonly reputationGate?: ReputationGateDecision; readonly atl: string; /** * Rule-of-Two assessment surfaced by the `policyEnforcement` stage (#3198): * present (`severity: 'block'`) when the effective tier is untrusted AND the * context has both write and secret access; `undefined` when the stage is * disabled or the rule holds. Since #5380 a view onto {@link policy} — its * `RULE_OF_TWO` entry — kept so existing consumers read the same field. */ readonly ruleOfTwoViolation?: Violation; /** * The `policyEnforcement` stage's full verdict (#5380). **Absent means the * stage did not run.** Its `scope` says how much of `evaluatePolicy` could be * evaluated ({@link FirewallPolicyEvaluation}), so "seven checks, none fired" * is distinguishable from "one check, six unmeasured". `wouldRefuse` and the * `enforce` refusal both derive from `policy.violations`, whichever scope. */ readonly policy?: FirewallPolicyEvaluation; /** * The rollout mode this run was evaluated under (#5382). Recorded on the * result rather than left implicit so a consumer reading a verdict can tell * WHICH policy produced it — a result that does not say which rules were in * force cannot be audited later. */ readonly policyMode: FirewallPolicyMode; /** * Whether `enforce` would have refused this input. * * This is what makes `audit` mode measurable, and it is the field that makes * the mode a real gate rather than a switch with two indistinguishable * settings: under `audit` the answer is computed and reported while the input * is still allowed through, so an operator can size the impact of flipping to * `enforce` before flipping it. * * Always `false` under `enforce`, because an input that would be refused IS * refused — it comes back as a `POLICY_REFUSED` error, not a result. */ readonly wouldRefuse: boolean; readonly auditEvents: readonly { readonly id: string; readonly type: string; }[]; /** * Whether a durable `AuditLogger` was configured for this instance (#4992 * review). `configured` means this run's events were HANDED to that logger; * delivery to the hash chain is subject to the logger's own severity filter * (trust events are `info`), its bounded queue and its timed, fail-loud * flush, and is NOT confirmed per call — the write is queued. `none` means * the events exist only in the in-memory trail, which the next `process()` * call clears. This is a construction-time fact, not a per-call outcome. */ readonly auditSink: 'configured' | 'none'; readonly durationMs: number; } /** * Outcome of {@link HostileInputFirewall.validateAction} (#5382). * * A discriminated union rather than a struct with optional fields, deliberately: * a caller cannot read `satisfied` without first narrowing on `evaluated`, so * "the stage did not run" is structurally impossible to misread as "the stage * ran and passed". `stages.corroboration` defaults to `false`, which makes the * unevaluated branch the COMMON case — exactly where a silent `satisfied: true` * would do the most damage. */ type ActionValidation = { readonly evaluated: false; /** Why no verdict exists. Absence is attributable, not anonymous. */ readonly reason: 'corroboration-stage-disabled'; readonly policyMode: FirewallPolicyMode; } | { readonly evaluated: true; readonly satisfied: boolean; /** Unmet corroboration requirements; empty when satisfied. */ readonly missing: readonly string[]; readonly corroboratingSources: readonly SourceCitation[]; /** * The validator's #5796 marker: the floor was cleared, and only by * `repoFile` citations the producer found absent from the base ref. * Carried so a consumer can report it without re-deriving the rule. */ readonly clearedOnlyByUnverifiedSources: boolean; readonly policyMode: FirewallPolicyMode; /** Whether `enforce` would have refused this action (see FirewallResult). */ readonly wouldRefuse: boolean; }; /** * Orchestrates existing security modules into a configurable pipeline. * Each stage is independently toggleable via config.stages. */ declare class HostileInputFirewall { private readonly stages; /** * Construction-time allowlist, or `undefined` when none was supplied (#4992). * The Zod default of `[]` is deliberately NOT taken here: an absent list and * an empty list must stay distinguishable so `isAllowlisted` can be omitted * rather than recorded as `false` when nothing was consulted. */ private readonly allowlisted; private readonly maxInputLength; private readonly adapter; private readonly reputationCache; private readonly auditTrail; private readonly context; /** #5382 rollout gate; resolved once at construction, not per call. */ private readonly policyMode; /** #5381 reputation-demotion gate; a DIFFERENT knob from `policyMode`. */ private readonly reputationGatingMode; /** #5405 seam: how a reputation assessment is obtained. */ private readonly assessReputationFn; /** #4992: whether the sanitizer's content tier downgrades the classifier tier. */ private readonly contentDowngrade; /** #4992 review: whether a durable logger was configured (not per-call delivery). */ private readonly auditSink; constructor(config: FirewallConfig); /** * Processes untrusted input through the firewall pipeline. * Returns a structured FirewallResult or a typed FirewallError. * * `options` carries the per-call facts (#4992): the repository's maintainer * allowlist and the caller's access posture. Each replaces its * construction-time counterpart for this call only, so one shared instance * never holds a repository's allowlist or a caller's posture process-wide. */ process(input: unknown, options?: FirewallProcessOptions): Result; /** * Runs the policy checks the call's facts allow — see * {@link evaluateFirewallPolicy} (#5380; Rule-of-Two-only since #3198). The * decision reaches the audit trail when the audit stage is on. Returns * `undefined` when the stage is disabled, so absence keeps meaning "not run". */ private runPolicyEnforcement; /** * Builds the successful result. Optional fields are spread in only when they * were evaluated, so absence keeps meaning "not measured" (see the field * docs on {@link FirewallResult}). */ private assembleResult; /** * Validates corroboration for a decided action (#5382). * * Separate from {@link process} because the two operate at different points * in the lifecycle, which is the real shape of the divergence epic #5281 * found: `process()` is INPUT-shaped — it sanitizes, classifies and labels * untrusted content — while corroboration is ACTION-shaped, asking whether a * decision the consumer has now reached is backed by sources of sufficient * tier. There is no `AgentAction` in scope during `process()`, so the * `stages.corroboration` flag could never have been wired there; this is the * entry point that makes it readable. * * It is also the shape #5383 needs: production validates corroboration per * action (`issue-triage.ts:391`), so those callers cannot migrate onto the * firewall unless it offers a per-action surface. * * Returns `evaluated: false` when the stage is disabled — never a satisfied * verdict for a check that did not run. Under `enforce` an unsatisfied action * is refused with `POLICY_REFUSED`; under `audit` the would-be refusal is * reported via `wouldRefuse` and the action is allowed through. */ validateAction(action: AgentAction): Result; /** Returns the internal audit trail for inspection. */ getAuditTrail(): AuditTrail; private runExtraction; private runSanitization; private runClassification; /** * Emits the trust audit event for the tier the consumer acts on — after the * reputation gate, so the record cannot describe a tier nobody enforced * (#4992 review). A demotion is named in `reason`. */ private recordTrustDecision; /** * Reconcile the classifier tier with reputation, under the rollout mode * production honours (#3106 reconciliation, #5381 gating). * * #3106's reconciliation is demotion-only; Tier-1/allowlist wins; it equals * the classifier tier when reputation is absent. #5381 puts it behind * `NEXUS_REPUTATION_GATING`, so `audit` is audit-only here too — previously * the firewall enforced unconditionally while production suppressed, on * identical configuration. * * Returns no gate at all when the stage is off, so absence in the result * means "not evaluated" rather than "evaluated, nothing suppressed" — * `demotionSuppressed` is a required boolean and would otherwise report * `false` for a check that never ran. */ private runReputationGate; private runReputation; private buildATL; } /** * nexus-agents/security/firewall - Agent Trust Labels (ATL) * * Generates and parses structured trust labels that travel with * processed inputs through the agent pipeline. Format: * [ATL:tier=3,source=github-comment,user=octocat,sanitized=true,rep=0.45] * * @module security/firewall/agent-trust-labels * (Source: Issue #826 — Reusable Hostile Input Firewall) */ /** * Generates an Agent Trust Label string from structured data. * * @example * generateATL({ tier: '3', source: 'github-comment', user: 'octocat', sanitized: true }) * // => "[ATL:tier=3,source=github-comment,user=octocat,sanitized=true]" */ declare function generateATL(data: ATLData): string; /** * Parses an ATL string back into structured data. * Returns undefined if the string is not a valid ATL. */ declare function parseATL(atl: string): ATLData | undefined; /** * nexus-agents/security/firewall - GitHub Adapter * * ISourceAdapter implementation for GitHub issues, PRs, and comments. * Extracts normalized metadata from GitHub API payloads. * * @module security/firewall/github-adapter * (Source: Issue #826 — Reusable Hostile Input Firewall) */ declare const GitHubInputSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{ type: z.ZodLiteral<"issue">; username: z.ZodString; authorAssociation: z.ZodString; title: z.ZodDefault; body: z.ZodDefault; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"comment">; username: z.ZodString; authorAssociation: z.ZodString; body: z.ZodDefault; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"pull_request">; username: z.ZodString; authorAssociation: z.ZodString; title: z.ZodDefault; body: z.ZodDefault; }, z.core.$strip>], "type">; type GitHubInput = z.infer; /** * Creates a GitHub source adapter. * Validates input with Zod and maps GitHub API fields to SourceMetadata. */ declare function createGitHubAdapter(): ISourceAdapter; /** * nexus-agents/security - Polyglot (Python/Go) AST QA/Security Rule Runner (#4249 child C) * * Runs YAML-defined `@ast-grep/napi` rules against Python/Go source, detecting * common QA/security anti-patterns (dynamic `eval`/`exec`, shell injection, * unchecked external command execution). Same engine already used by * `search_usages` (indexer/usage-ast.ts, #4265) and the ast-fixer rewrites * (agents/collaboration/ast-rewrites.ts, #4243/#4249 child B) — no new AST * dependency, just new language grammars for it. * * **Language support gap.** `Lang` in `@ast-grep/napi@0.44.1` ships only * Html/JavaScript/Tsx/Css/TypeScript — no Python, no Go. This module closes * that gap via napi's `@experimental registerDynamicLanguage` API, backed by * the `@ast-grep/lang-python`/`@ast-grep/lang-go` prebuilt tree-sitter * grammars. Both are EXACT-pinned in package.json (no caret): these are * early/experimental packages and a caret range could silently swap in an * incompatible native `.so` grammar build underneath a "safe" semver-minor * bump. `registerDynamicLanguage` throws if called more than once per * process (napi-rs's own documented constraint) — {@link ensurePolyglotLangs} * is a lazy, module-level, once-only guard so repeated calls (tests, repeat * runner invocations within one process) never trip it twice. * * **Read-only.** Reads rule YAML and target source files, walks their ASTs, * performs NO writes. ast-grep YAML rule files support a `fix:` key for * autofixing, but napi's `SgNode.findAll` (used here) never applies it — * only ast-grep's separate rewrite/CLI machinery does — so even a rule * author who adds `fix:` cannot turn this runner into a writer by accident. * MCP exposure is deliberately deferred (see the follow-up issue referenced * in the #4249 child C PR) to keep this surface a plain function until a * named consumer needs it wired through a tool. * * @module security/ast-rule-runner * @see Issue #4249 - epic: ast-grep adoption (Child C: polyglot QA/security rules) */ /** * Lazily register the Python/Go tree-sitter grammars with ast-grep's * `registerDynamicLanguage`. That API throws if called more than once in a * process; this guard makes every call after the first a no-op so repeated * runner invocations (or a test suite that constructs the runner many times) * never trip the constraint. */ declare function ensurePolyglotLangs(): void; /** Languages a rule file may declare. Deliberately narrowed to the two this * runner actually SCANS (python/go): admitting `typescript`/`javascript` here * would let a TS/JS rule file validate at load time and then silently never * fire (there is no TS/JS extension in {@link POLYGLOT_EXT_TO_LANG}), which is * a fail-OPEN gap for a security scanner where "no findings" reads as "clean". * TS/JS structural analysis is already covered by `search_usages` (#4265) and * the ast-fixer rewrites (#4243); a TS/JS rule here would fail LOUD at load * (unknown-language Zod error) instead of loading dead. */ declare const AST_RULE_LANGUAGES: readonly ["python", "go"]; type AstRuleLanguage = (typeof AST_RULE_LANGUAGES)[number]; declare const AST_RULE_SEVERITIES: readonly ["error", "warning", "info"]; type AstRuleSeverity = (typeof AST_RULE_SEVERITIES)[number]; /** Schema for one `*.yml` rule file. `rule` is passed through as ast-grep's * own `Rule` object (napi already validates it structurally at match time); * Zod only pins down the envelope so an unknown `language` or a missing * field FAILS CLOSED instead of silently loading a partial/broken rule. */ declare const RuleFileSchema: z.ZodObject<{ id: z.ZodString; language: z.ZodEnum<{ python: "python"; go: "go"; }>; severity: z.ZodEnum<{ error: "error"; info: "info"; warning: "warning"; }>; message: z.ZodString; rule: z.ZodRecord; }, z.core.$strip>; type AstQaRuleFile = z.infer; /** Default cap on emitted findings. Excess is counted + reported, never silently dropped. */ declare const DEFAULT_AST_QA_LIMIT = 200; /** Hard upper bound a caller may request for the finding cap. */ declare const MAX_AST_QA_LIMIT = 2000; /** Upper bound on files parsed in a single run, to bound worst-case cost. * Exceeding it makes the scan PARTIAL — surfaced via {@link AstQaCollectResult}'s * `filesTruncated`/`filesSkipped` + a warn, never silently dropped. */ declare const MAX_FILES_SCANNED = 5000; /** * Load and Zod-validate every `*.yml` rule file in `dir`. FAILS CLOSED: a * single malformed YAML file, or a file with an unrecognized `language` or * missing field, throws a {@link ValidationError} — there is no * "load what parsed, skip the rest" partial mode. */ declare function loadRules(dir: string): Promise; /** * Resolve the built-in `ast-rules/` directory, handling both dev (unbundled, * `src/security/ast-rule-runner.ts`) and published (bundled, * `dist/index.js` + `dist/security/ast-rules/*.yml` copied by tsup's * `onSuccess` step) layouts — the same two-layout problem * `getBuiltInTemplatesPath` solves for workflow templates. */ declare function getBuiltInAstRulesPath(): string; /** One ast-grep rule match against a source file. */ interface AstRuleFinding { ruleId: string; severity: AstRuleSeverity; message: string; /** Path relative to the resolved `targetDir`. */ file: string; /** 1-based line number. */ line: number; /** 1-based column number. */ column: number; /** Trimmed, length-capped source line for the match. */ snippet: string; } interface RunAstQaRulesOptions { /** Directory containing `*.yml` rule files (default: the built-in bundled rules). */ rulesDir?: string; /** Directory to scan for `.py`/`.go` source files (must stay within cwd). */ targetDir: string; /** Max findings emitted (default {@link DEFAULT_AST_QA_LIMIT}). Excess is counted + reported. */ limit?: number; } /** {@link collectAstQaFindings}'s full result — findings plus the true total, * so overflow beyond `limit` is counted and reported, never silently dropped. */ interface AstQaCollectResult { findings: AstRuleFinding[]; /** True count of matches found, before the `limit` cap was applied. */ total: number; limit: number; /** Number of `.py`/`.go` files actually scanned (after the file cap). */ filesScanned: number; /** Number of discovered files DROPPED because the file cap ({@link MAX_FILES_SCANNED}) * was exceeded. Non-zero means the scan was PARTIAL — a downstream consumer * must not treat empty/low findings as a clean bill of health. */ filesSkipped: number; /** True iff `filesSkipped > 0` — the scan did not cover every candidate file. */ filesTruncated: boolean; } /** * Run every applicable rule in `rulesDir` against every `.py`/`.go` file under * `targetDir`, returning capped findings plus the true total (so callers that * need the overflow count — e.g. a future MCP tool wrapper — can report it). * {@link runAstQaRules} is the capped-array convenience wrapper over this. */ declare function collectAstQaFindings(opts: RunAstQaRulesOptions): Promise; /** * Run the polyglot QA/security ast-grep rules and return the capped findings * array. Overflow beyond `limit` is counted and logged (never silently * dropped) — use {@link collectAstQaFindings} directly when the caller needs * the true total/overflow count programmatically. */ declare function runAstQaRules(opts: RunAstQaRulesOptions): Promise; /** * nexus-agents/orchestration - Orchestrator Adapters * * Adapters wrapping Orchestrator, PuppeteerOrchestrator, WorkflowEngine * to implement the unified IOrchestrator interface. * * @module orchestration/orchestrator-adapters * @see docs/adr/0002-orchestrator-interface.md */ /** * Narrow shape of an agent that the OrchestratorAdapter (and the factory * config that wires one in) needs. Narrows the input to `Task` so the * concrete `Orchestrator` instance can be passed without an `as unknown * as` cast (#2944). Keeps the `Result` payload+error wide because the * adapter is intentionally resilient to non-`AgentError` failures * (see orchestrator-adapters.test.ts "fails with non-Error" coverage). */ interface OrchestratorAgentLike { execute(task: Task$1): Promise>; } /** * nexus-agents/orchestration - Orchestrator Factory * * Factory for creating IOrchestrator instances. * Provides a unified entry point for all orchestration strategies. * * Per ADR-0002: Unified Interface + Adapters pattern. * * @module orchestration/orchestrator-factory * @see docs/adr/0002-orchestrator-interface.md */ /** * Configuration for WorkflowOrchestratorAdapter. */ interface WorkflowAdapterConfig extends WorkflowEngineFactoryConfig { /** Custom logger */ logger?: ILogger; } /** * Adapter that wraps IWorkflowEngine with IOrchestrator interface. * * This adapter bridges the workflow-specific interface to the canonical * orchestrator interface, enabling workflow-based orchestration through * the unified IOrchestrator contract. */ declare class WorkflowOrchestratorAdapter implements IOrchestrator { readonly id: string; readonly type: OrchestratorType; private readonly engine; private readonly logger; private readonly executions; private readonly history; constructor(engine: IWorkflowEngine, logger?: ILogger); execute(definition: OrchestratorDefinition, inputs: Record, _options?: OrchestratorExecuteOptions): Promise>; private setRunning; private setFailed; private executeWorkflow; private addToHistory; /** Evicts completed/cancelled entries from executions map to prevent unbounded growth. */ private evictCompletedExecutions; getStatus(executionId: string): ExecutionStatus; cancel(executionId: string, reason?: string): Promise>; getHistory(limit?: number): OrchestratorResult[]; private convertWorkflowResult; } /** * Configuration for OrchestratorFactory. * (Enhanced per ADR-0014 - Orchestrator Interface Unification) */ interface OrchestratorFactoryConfig { /** Logger instance */ logger?: ILogger; /** Model adapter for agent-based orchestrators */ modelAdapter?: IModelAdapter; /** Workflow engine config */ workflowConfig?: WorkflowEngineFactoryConfig; /** * Pre-created orchestrator agent instance for orchestrator adapter. * Narrowed from `(task: unknown)` to `OrchestratorAgentLike` so a real * `Orchestrator` instance can be passed without an `as unknown as` cast * (#2944). Task-input contract matches `OrchestratorAdapter.setOrchestrator`. */ techLead?: OrchestratorAgentLike; /** Alias for techLead (preferred, Issue #759) */ orchestratorAgent?: OrchestratorAgentLike; /** * Pre-created PuppeteerOrchestrator instance. Input stays `unknown` * because Puppeteer accepts arbitrary policy-shaped tasks, not the * core `Task` type that the regular agent path requires. */ puppeteerOrchestrator?: { execute(task: unknown): Promise>; }; } /** * Factory for creating IOrchestrator instances. * * Provides a unified entry point for all orchestration strategies: * - workflow: Static template-based execution * - tech_lead: LLM-based task decomposition and orchestration (OrchestratorAdapter) * - puppeteer: Policy-based step execution (PuppeteerAdapter) * * @example * ```typescript * const factory = await createOrchestratorFactory(); * const orchestrator = factory.create('workflow'); * * const result = await orchestrator.execute( * { type: 'workflow', templatePath: './templates/code-review.yaml' }, * { url: 'https://github.com/...' } * ); * ``` */ declare class OrchestratorFactory implements IOrchestratorFactory { private readonly logger; private readonly workflowEngine; private readonly config; constructor(config: OrchestratorFactoryConfig, workflowEngine?: IWorkflowEngine); create(type: OrchestratorType, _config?: Record): IOrchestrator; listTypes(): OrchestratorType[]; } /** * Creates an OrchestratorFactory with async initialization. * * This is the recommended way to create an OrchestratorFactory as it * properly initializes all async dependencies like the WorkflowEngine. * * @param config - Factory configuration * @returns Promise resolving to initialized OrchestratorFactory * * @example * ```typescript * const factory = await createOrchestratorFactory(); * const types = factory.listTypes(); // ['workflow'] * * const orchestrator = factory.create('workflow'); * const result = await orchestrator.execute(...); * ``` */ declare function createOrchestratorFactory(config?: OrchestratorFactoryConfig): Promise; /** * Type definitions for the Spec Parser module. * * Parses markdown specification documents into typed structures * that drive autonomous implementation workflows. * * @module orchestration/spec-parser-types * (Source: Issue #847 — Phase 2 of AI Software Factory Epic #843) */ /** * A reference to a GitHub issue or PR extracted from spec text. */ declare const IssueReferenceSchema: z.ZodObject<{ number: z.ZodNumber; raw: z.ZodString; }, z.core.$strip>; type IssueReference = z.infer; /** * A reference to a file path extracted from spec text. */ declare const FileReferenceSchema: z.ZodObject<{ path: z.ZodString; line: z.ZodOptional; }, z.core.$strip>; type FileReference = z.infer; /** * Parsed specification from a markdown document. */ declare const ParsedSpecSchema: z.ZodObject<{ title: z.ZodString; overview: z.ZodString; requirements: z.ZodArray; acceptanceCriteria: z.ZodArray; constraints: z.ZodArray; issueReferences: z.ZodArray>; fileReferences: z.ZodArray; }, z.core.$strip>>; missingSections: z.ZodArray; rawMarkdown: z.ZodString; techStack: z.ZodOptional; framework: z.ZodOptional; packageManager: z.ZodOptional; }, z.core.$strip>>; }, z.core.$strip>; type ParsedSpec = z.infer; /** * Error detail when spec parsing fails. */ interface SpecParseError { readonly message: string; readonly section?: string | undefined; } /** * Known section headings that the parser recognizes. */ declare const KNOWN_SECTIONS: readonly ["overview", "requirements", "acceptance criteria", "constraints", "goal", "description", "design", "dependencies"]; type KnownSection = (typeof KNOWN_SECTIONS)[number]; /** * Spec Parser — parses markdown specifications into typed structures. * * Entry point for autonomous implementation: specs are the deliverable. * Extracts structured data from markdown sections, issue references, * and file references. * * @module orchestration/spec-parser * (Source: Issue #847 — Phase 2 of AI Software Factory Epic #843) */ /** * Parses a markdown specification into a typed ParsedSpec structure. * * Extracts title, overview, requirements, acceptance criteria, constraints, * and references from a well-structured markdown document. */ declare function parseSpec(markdown: string): Result; /** * Type definitions for the Spec Decomposer module. * * Decomposes parsed specs into dependency DAGs of typed subtasks * for autonomous agent execution. * * @module orchestration/spec-decomposer-types * (Source: Issue #848 — Phase 2 of AI Software Factory Epic #843) */ /** * The type of work a subtask represents. */ declare const SubtaskTypeSchema: z.ZodEnum<{ code: "code"; refactor: "refactor"; test: "test"; docs: "docs"; config: "config"; }>; type SubtaskType = z.infer; /** * Complexity level for a subtask. */ declare const ComplexityLevelSchema: z.ZodEnum<{ simple: "simple"; complex: "complex"; expert: "expert"; moderate: "moderate"; }>; type ComplexityLevel = z.infer; /** * A single decomposed subtask node in the DAG. */ declare const SubtaskNodeSchema: z.ZodObject<{ id: z.ZodString; description: z.ZodString; type: z.ZodEnum<{ code: "code"; refactor: "refactor"; test: "test"; docs: "docs"; config: "config"; }>; complexity: z.ZodEnum<{ simple: "simple"; complex: "complex"; expert: "expert"; moderate: "moderate"; }>; capabilities: z.ZodArray; dependsOn: z.ZodArray; sourceRequirement: z.ZodOptional; }, z.core.$strip>; type SubtaskNode = z.infer; /** * A directed edge in the dependency DAG. */ declare const DagEdgeSchema: z.ZodObject<{ from: z.ZodString; to: z.ZodString; }, z.core.$strip>; type DagEdge = z.infer; /** * The complete dependency DAG produced by decomposition. */ declare const TaskDagSchema: z.ZodObject<{ nodes: z.ZodArray; complexity: z.ZodEnum<{ simple: "simple"; complex: "complex"; expert: "expert"; moderate: "moderate"; }>; capabilities: z.ZodArray; dependsOn: z.ZodArray; sourceRequirement: z.ZodOptional; }, z.core.$strip>>; edges: z.ZodArray>; roots: z.ZodArray; totalComplexity: z.ZodEnum<{ simple: "simple"; complex: "complex"; expert: "expert"; moderate: "moderate"; }>; specTitle: z.ZodString; }, z.core.$strip>; type TaskDag = z.infer; /** * Error detail when decomposition fails. */ interface DecomposeError { readonly message: string; readonly subtaskId?: string | undefined; } /** * Spec Decomposer — breaks parsed specs into dependency DAGs. * * Accepts a ParsedSpec and produces a TaskDag where each requirement * maps to a subtask node and acceptance criteria map to test nodes. * * @module orchestration/spec-decomposer * (Source: Issue #848 — Phase 2 of AI Software Factory Epic #843) */ /** * Decomposes a parsed spec into a dependency DAG of typed subtasks. */ declare function decomposeSpec(spec: ParsedSpec): Result; /** * Type definitions for the Spec Pipeline module. * * Wires spec-parser, spec-decomposer, and GraphBuilder into * an end-to-end execution pipeline. * * @module orchestration/spec-pipeline-types * (Source: Issue #849 — Phase 2 of AI Software Factory Epic #843) */ /** * Which stage of the pipeline failed. */ type PipelineStage$1 = 'parse' | 'decompose' | 'compile'; /** * Error detail when the spec pipeline fails. */ interface PipelineError { readonly message: string; readonly stage: PipelineStage$1; } /** * A graph node handler function — takes state, returns partial state update. */ type NodeHandler = (state: Readonly) => Promise>; /** * Factory that creates graph node handlers from subtask nodes. * Allows plugging in different execution strategies (dry-run, expert delegation, etc.). * * (Source: Issue #857 — Pluggable node execution for AI Software Factory) */ type NodeHandlerFactory = (node: SubtaskNode) => NodeHandler; /** * Options for compiling a spec to a graph. */ interface CompileOptions { /** Factory for creating node handlers. Defaults to dry-run placeholders. */ readonly handlerFactory?: NodeHandlerFactory; } /** * Spec Pipeline — wires spec-parser + decomposer + GraphBuilder. * * Takes raw markdown and produces an executable compiled graph. * Each subtask becomes a graph node; dependencies become edges. * * @module orchestration/spec-pipeline * (Source: Issue #849 — Phase 2 of AI Software Factory Epic #843) */ /** * Creates the default dry-run node handler for a subtask. * Returns a placeholder string describing the subtask. */ declare function createDryRunHandler(node: SubtaskNode): (state: Readonly) => Promise>; /** * Compiles a markdown specification into an executable graph. * * Pipeline: markdown → parseSpec → decomposeSpec → GraphBuilder → CompiledGraph * * @param markdown - Raw markdown specification text * @param options - Optional compile options (handler factory, etc.) */ declare function compileSpecToGraph(markdown: string, options?: CompileOptions): Result; /** * Type definitions for the Scenario Validator module. * * Validates execution results against acceptance criteria * from parsed specifications. * * @module orchestration/scenario-validator-types * (Source: Issue #850 — Phase 3 of AI Software Factory Epic #843) */ /** * Result of checking a single acceptance criterion. */ declare const CriterionResultSchema: z.ZodObject<{ criterion: z.ZodString; met: z.ZodBoolean; matchedResults: z.ZodArray; partialResults: z.ZodArray; }, z.core.$strip>; type CriterionResult = z.infer; /** * Overall scenario validation result. */ declare const ScenarioResultSchema: z.ZodObject<{ satisfaction: z.ZodNumber; totalCriteria: z.ZodNumber; metCount: z.ZodNumber; criteria: z.ZodArray; partialResults: z.ZodArray; }, z.core.$strip>>; allMet: z.ZodBoolean; }, z.core.$strip>; type ScenarioResult = z.infer; /** * Error detail when scenario validation fails. */ interface ScenarioError { readonly message: string; } /** * Type definitions for the Spec Executor module. * * End-to-end spec execution: parse → decompose → compile → execute → validate. * * @module orchestration/spec-executor-types * (Source: Issue #851 — Phase 3 of AI Software Factory Epic #843) */ /** * Which stage of execution failed. */ type ExecutionStage = 'parse' | 'decompose' | 'compile' | 'execute' | 'validate'; /** * Error detail when spec execution fails. */ interface SpecExecutionError { readonly message: string; readonly stage: ExecutionStage; } /** * Options for spec execution. * (Source: Issue #857 — Pluggable node execution) */ type SpecExecutionOptions = CompileOptions & { /** * Called on every graph event the compiled spec's execution emits (node * started, step completed, …) — the async-job liveness heartbeat for * `execute_spec` (#6162), whose body emits nothing on the pipeline bus. */ readonly onProgress?: (() => void) | undefined; }; /** * Result of executing a spec end-to-end. */ interface SpecExecutionResult { /** Whether configured node handlers ran instead of dry-run placeholders */ readonly executed: boolean; /** The decomposed task DAG */ readonly dag: TaskDag; /** Raw execution outputs from graph nodes */ readonly outputs: readonly string[]; /** Scenario validation against acceptance criteria */ readonly validation: ScenarioResult; /** Total execution duration in milliseconds */ readonly durationMs: number; } /** * Spec Executor — end-to-end spec execution with validation. * * Takes raw markdown, compiles to a graph, executes it, and * validates results against acceptance criteria. * * @module orchestration/spec-executor * (Source: Issue #851 — Phase 3 of AI Software Factory Epic #843) */ /** Executes a markdown specification end-to-end. */ declare function executeSpec(markdown: string, options?: SpecExecutionOptions): Promise>; /** * Type definitions for the Failure Analyzer module. * * Analyzes execution results to detect failure patterns * and produce improvement suggestions. * * @module orchestration/failure-analyzer-types * (Source: Issue #852 — Phase 4 of AI Software Factory Epic #843) */ /** * Type of failure detected for an unmet criterion. */ type FailureType = 'missing_implementation' | 'partial_match' | 'no_output'; /** * A specific failure for one unmet criterion. */ interface CriterionFailure { /** The unmet acceptance criterion */ readonly criterion: string; /** What type of failure occurred */ readonly type: FailureType; /** Human-readable explanation */ readonly explanation: string; } /** * A suggested improvement to address failures. */ interface ImprovementSuggestion { /** What action to take */ readonly action: string; /** Which criterion this addresses */ readonly targetCriterion: string; /** Priority: 1 (highest) to 3 (lowest) */ readonly priority: 1 | 2 | 3; } /** * Complete failure analysis result. */ interface FailureAnalysis { /** Overall pass/fail */ readonly passed: boolean; /** Satisfaction score from validation (0-1) */ readonly satisfaction: number; /** Individual criterion failures */ readonly failures: readonly CriterionFailure[]; /** Suggested improvements */ readonly suggestions: readonly ImprovementSuggestion[]; } /** * Error from failure analysis. */ interface AnalysisError { readonly message: string; } /** * Failure Analyzer — detects failure patterns in spec execution results. * * Analyzes unmet acceptance criteria to categorize failures * and suggest improvements for the self-improvement loop. * * @module orchestration/failure-analyzer * (Source: Issue #852 — Phase 4 of AI Software Factory Epic #843) */ /** * Analyzes execution results for failure patterns. */ declare function analyzeFailures(executionResult: SpecExecutionResult): Result; /** * Scenario Validator — checks execution results against acceptance criteria. * * Uses keyword-based matching to determine which acceptance criteria * from a parsed spec are satisfied by execution results. * * @module orchestration/scenario-validator * (Source: Issue #850 — Phase 3 of AI Software Factory Epic #843) */ /** * Validates execution results against a spec's acceptance criteria. */ declare function validateScenario(spec: ParsedSpec, results: readonly string[]): Result; /** * nexus-agents/scm - SCM Provider Types * * Shared types for the centralized SCM (Source Control Management) module. * Supports GitHub (REST API + gh CLI) with extensibility for GitLab/Gitea. * * @module scm/types * (Source: Issue #1136 — Centralized SCM Provider Module) */ /** Supported SCM platforms. */ type ScmPlatform = 'github' | 'gitlab' | 'gitea'; /** Token resolution strategy. */ type TokenStrategy = 'env' | 'cli' | 'config'; /** Resolved SCM token with metadata. */ interface ScmToken { /** The raw token value */ readonly value: string; /** How the token was resolved */ readonly strategy: TokenStrategy; /** SCM platform this token is for */ readonly platform: ScmPlatform; } /** Token resolution configuration. */ interface TokenResolverConfig { /** Explicit token (highest priority) */ readonly token?: string; /** SCM platform to resolve for */ readonly platform?: ScmPlatform; /** Custom env var name override */ readonly envVar?: string; } /** SCM issue representation. */ interface ScmIssue { readonly number: number; readonly title: string; readonly body: string; readonly labels: readonly string[]; readonly author: string; readonly createdAt: string; /** * Web URL of the issue, when the producer has it. * * `createIssue` gets it from `gh issue create`'s stdout and used to discard * it, which left a caller with no way to recover the identity if the number * could not be scraped — and `pipeline/task-tracker.ts` was already reading * `url` through a cast, so `TrackedTask.url` was permanently `undefined` on * the GitHub path. Optional because `mapIssue` builds from a `--json` field * list that does not request it. */ readonly url?: string | undefined; } /** SCM pull/merge request representation. */ interface ScmPullRequest { readonly number: number; readonly title: string; readonly body: string; readonly author: string; readonly base: string; readonly head: string; readonly url: string; } /** SCM comment representation. */ interface ScmComment { readonly id: number; readonly body: string; readonly author: string; readonly createdAt: string; } /** PR creation options. */ interface CreatePROptions { readonly title: string; readonly body: string; readonly head: string; readonly base: string; } /** PR merge options. */ interface MergePROptions { readonly method?: 'merge' | 'squash' | 'rebase'; readonly commitTitle?: string; readonly commitMessage?: string; readonly deleteBranch?: boolean; } /** PR status for merge eligibility. */ interface PRStatus { readonly mergeable: boolean; readonly checksStatus: 'pending' | 'success' | 'failure'; readonly reviewStatus: 'approved' | 'pending' | 'changes_requested'; } /** Issue filter options. */ interface IssueFilters { readonly labels?: readonly string[]; readonly state?: 'open' | 'closed' | 'all'; readonly limit?: number; } /** Unified SCM error with platform-aware context. */ declare class ScmError extends Error { readonly platform: ScmPlatform; readonly statusCode?: number | undefined; readonly context?: Record | undefined; constructor(message: string, platform: ScmPlatform, statusCode?: number | undefined, context?: Record | undefined); } /** File change in a pull request. */ interface ScmFileChange { readonly filename: string; readonly status: 'added' | 'removed' | 'modified' | 'renamed' | 'copied' | 'changed' | 'unchanged' | 'unknown'; readonly rawStatus?: string; readonly additions: number; readonly deletions: number; readonly patch?: string; readonly previousFilename?: string; } /** Extended PR with file diffs and stats. Used by IScmReviewer. */ interface ScmPullRequestDetail extends ScmPullRequest { readonly draft: boolean; readonly authorAssociation: string; readonly labels: readonly string[]; readonly files: readonly ScmFileChange[]; readonly additions: number; readonly deletions: number; readonly headSha: string; } /** Extended issue with association and state. Used by IScmReviewer. */ interface ScmIssueDetail extends ScmIssue { readonly authorAssociation: string; readonly state: string; readonly url: string; } /** Extended comment with author association. */ interface ScmCommentDetail extends ScmComment { readonly authorAssociation: string; } /** Review decision for a pull request. */ type ScmReviewDecision = 'approve' | 'request_changes' | 'comment'; /** User metadata for reputation assessment. */ interface ScmUserMetadata { readonly login: string; readonly name: string | null; readonly company: string | null; readonly followers: number; readonly following: number; readonly publicRepos: number; readonly createdAt: string; } /** * Core SCM provider interface. * * All methods return `Result` for consistent error handling * across GitHub REST API, gh CLI, and future GitLab/Gitea backends. */ interface IScmProvider { /** Platform identifier. */ readonly platform: ScmPlatform; /** Repository in owner/repo format. */ readonly repo: string; getIssue(number: number): Promise>; listIssues(filters?: IssueFilters): Promise>; listRepositoryLabels(): Promise>; createIssue(title: string, body: string, labels?: readonly string[]): Promise>; addLabels(issueNumber: number, labels: readonly string[]): Promise>; createPR(options: CreatePROptions): Promise>; mergePR(prNumber: number, options?: MergePROptions): Promise>; getPRStatus(prNumber: number): Promise>; addComment(issueNumber: number, body: string): Promise>; listComments(issueNumber: number): Promise>; } /** * Review trait — PR review capabilities. * * Implemented by platforms supporting code review workflows. * Consumers declare this trait when they need PR file diffs or review posting. */ interface IScmReviewer { /** Fetch PR with full file diffs and stats. */ getPullRequestDetail(prNumber: number): Promise>; /** Post a review on a pull request. */ createReview(prNumber: number, body: string, decision: ScmReviewDecision): Promise>; /** Fetch issue with author association and state. */ getIssueDetail(issueNumber: number): Promise>; /** List comments with author associations. */ listCommentDetails(issueNumber: number): Promise>; } /** * User info trait — user metadata for reputation assessment. * * Implemented by platforms supporting user profile queries. * Consumers declare this trait when they need author reputation data. */ interface IScmUserInfo { /** Fetch user metadata for reputation assessment. */ fetchUserMetadata(username: string): Promise>; } /** * Convenience type: provider with review capabilities. * Used by PR review workflows. */ type ReviewCapableProvider = IScmProvider & IScmReviewer; /** * Convenience type: provider with all capabilities. * Used by full triage workflows that need review + user info. */ type FullCapableProvider = IScmProvider & IScmReviewer & IScmUserInfo; /** * nexus-agents/consensus - Voting Strategies * * Implementation of different voting strategies for consensus engine. * Supports simple majority, supermajority, unanimous, and proof-of-learning. */ /** * Interface for voting strategy implementations. */ interface IVotingStrategy { readonly algorithm: ConsensusAlgorithm; calculateOutcome(votes: Map, weights?: Map): VotingOutcome; } /** * Result of a voting strategy calculation. */ interface VotingOutcome { approved: boolean; approvalPercentage: number; voteCounts: VoteCounts; weightedCounts?: WeightedVoteCounts; /** * Present on weighted strategies only. Absent means the strategy does not * weight at all (simple majority, supermajority, unanimous) — which is * different from `'unweighted'`, meaning a weighted strategy ran with nothing * to weight by. */ weightBasis?: WeightBasis; reason: string; } /** * Base voting strategy with common functionality. */ declare abstract class BaseVotingStrategy implements IVotingStrategy { abstract readonly algorithm: ConsensusAlgorithm; abstract calculateOutcome(votes: Map, weights?: Map): VotingOutcome; /** * Count votes by decision type. */ protected countVotes(votes: Map): VoteCounts; /** * Calculate weighted vote counts using agent performance weights. */ protected countWeightedVotes(votes: Map, weights: Map): WeightedVoteCounts; } /** * Simple majority voting strategy (>50% approval). */ declare class SimpleMajorityStrategy extends BaseVotingStrategy { readonly algorithm: ConsensusAlgorithm; calculateOutcome(votes: Map): VotingOutcome; } /** * Supermajority voting strategy (at least 2/3 approval). */ declare class SupermajorityStrategy extends BaseVotingStrategy { readonly algorithm: ConsensusAlgorithm; calculateOutcome(votes: Map): VotingOutcome; } /** * Unanimous voting strategy (100% approval required). */ declare class UnanimousStrategy extends BaseVotingStrategy { readonly algorithm: ConsensusAlgorithm; calculateOutcome(votes: Map): VotingOutcome; } /** * Proof-of-learning weighted voting strategy. * Agents with better track records have more voting power. */ declare class ProofOfLearningStrategy extends BaseVotingStrategy { readonly algorithm: ConsensusAlgorithm; calculateOutcome(votes: Map, weights?: Map): VotingOutcome; } /** * Calculate vote weight for an agent based on their performance history. * * Weight ranges from 0.5 (never correct) to 1.0 (perfect track record). An * agent with NO history returns 1.0, not 0.5 — the doc used to say "0.5 (no * history)", which the code has never done (#5117). The distinction matters: * a 1.0 default is indistinguishable from a perfect record by value alone, * which is why callers must not infer "was this measured?" from the number. * `deriveWeightBasis` answers that from provenance instead. */ declare function calculateVoteWeight(performance: AgentPerformance | undefined): number; /** * Factory for creating voting strategies. */ declare class VotingStrategyFactory { private readonly strategies; constructor(); /** * Get a voting strategy by algorithm type. */ getStrategy(algorithm: ConsensusAlgorithm): IVotingStrategy; /** * Register a custom voting strategy. */ registerStrategy(strategy: IVotingStrategy): void; /** * Get all available algorithm types. */ getAvailableAlgorithms(): ConsensusAlgorithm[]; } /** * Creates a voting strategy factory with default strategies. */ declare function createStrategyFactory(): VotingStrategyFactory; /** * nexus-agents/consensus - Result Builder * * Helper functions for building consensus results. */ /** * Build a pending result for an active proposal. */ declare function buildPendingResult(state: ProposalState, proposalId: ProposalId, outcome: VotingOutcome, config: ConsensusEngineConfig): ConsensusResult; /** * Build a final result for a closed proposal. */ declare function buildFinalResult(state: ProposalState, proposalId: ProposalId, outcome: VotingOutcome, config: ConsensusEngineConfig): ConsensusResult; /** * Build a timeout result for an expired proposal. */ declare function buildTimeoutResult(state: ProposalState, proposalId: ProposalId, outcome: VotingOutcome, config: ConsensusEngineConfig): ConsensusResult; /** * nexus-agents/consensus - Helper Functions * * Utility functions for the consensus engine. */ /** * Generate a unique proposal ID. */ declare function generateProposalId(): ProposalId; /** * nexus-agents/consensus - Consensus Engine * * Core consensus engine implementation supporting multiple voting strategies. * Manages proposal lifecycle, vote collection, and outcome determination. */ /** * Error class for consensus-related failures. */ declare class ConsensusError extends AgentError$1 { constructor(message: string, context?: Record); } /** * Interface for the consensus engine. */ interface IConsensusEngine { propose(proposal: Proposal): Promise>; vote(proposalId: ProposalId, agentId: string, vote: Vote): Promise>; getResult(proposalId: ProposalId): Promise>; close(proposalId: ProposalId): Promise>; getMetrics(): ConsensusMetrics; } /** * Consensus engine for multi-agent decision making. * * @example * ```typescript * const engine = new ConsensusEngine({ defaultTimeout: 30000 }); * const proposalResult = await engine.propose({ * title: 'Use microservices architecture', * description: 'Proposal to adopt microservices', * algorithm: 'supermajority', * }); * if (proposalResult.ok) { * await engine.vote(proposalResult.value, 'agent-1', { * decision: 'approve', * confidence: 0.9, * reasoning: 'Good for scalability', * }); * } * ``` */ declare class ConsensusEngine implements IConsensusEngine { private readonly proposals; private readonly closedProposals; private readonly agentPerformance; private readonly proposalContentCache; private readonly strategyFactory; private readonly config; private readonly cacheConfig; private readonly quorumConfig; private readonly logger; private readonly metrics; private voterExpansionCallback?; constructor(config?: Partial, logger?: ILogger); /** * Sets the callback for incremental quorum voter expansion (Issue #1408). * When ambiguous votes are detected, this callback requests additional voters. */ setVoterExpansionCallback(callback: VoterExpansionCallback): void; propose(proposal: Proposal): Promise>; vote(proposalId: ProposalId, agentId: string, vote: Vote): Promise>; getResult(proposalId: ProposalId): Promise>; close(proposalId: ProposalId): Promise>; getMetrics(): ConsensusMetrics; updateAgentPerformance(agentId: string, wasCorrect: boolean): void; getAgentPerformance(agentId: string): AgentPerformance | undefined; getActiveProposalCount(): number; private createProposalState; private setupTimeout; private registerProposal; private validateVote; private validateProposalState; private recordVote; private closeInternal; private handleTimeout; private finalize; /** * Adds a closed proposal and evicts oldest entries if over limit. * Issue #549: Prevent unbounded memory growth in closedProposals Map. */ private addClosedProposal; private calculateOutcome; /** * Agreement-based cascading: close early when outcome is mathematically determined. * * #2822: the prior implementation computed approval rates against * `totalExpected = requiredVoters.length` and compared against * `VOTING_THRESHOLDS[algorithm]` directly. Every voting strategy * (`SimpleMajorityStrategy`, `SupermajorityStrategy`, `UnanimousStrategy`, * `ProofOfLearningStrategy`) uses `approve + reject` as its denominator — * abstains are explicitly excluded. The two diverged whenever abstains * were present, producing wrong-winner cascades (e.g. 5-voter supermajority * with [approve, abstain, abstain, abstain, pending] cascade-rejected even * though the strategy would approve at close). * * The fix delegates to the strategy itself: build a best-case (all pending * voters approve) and worst-case (all pending voters reject) hypothetical * vote map, call `strategy.calculateOutcome` on each, and cascade only * when both extremes yield the same outcome. This guarantees parity with * the strategy's denominator semantics by construction. */ private canCascadeEarly; private allRequiredVotersVoted; /** * Attempts incremental quorum expansion when voting is ambiguous (Issue #1408). * Returns true if expansion occurred (wait for new voters), false to close immediately. */ private tryExpandQuorum; private updateMetrics; private createInitialMetrics; /** * Creates a content hash for a proposal to enable cache lookups. * Hash is based on title, description, and algorithm (deterministic content). */ private hashProposalContent; /** * Gets cached result for a proposal if it exists and hasn't expired. */ private getCachedResult; /** * Adds a proposal result to the cache, evicting oldest entries if needed. */ private addToCache; /** * Gets the current cache size (for testing/monitoring). */ getCacheSize(): number; /** * Clears the proposal content cache (for testing/reset). */ clearCache(): void; } /** * Create a consensus engine with the given configuration. * * @example * ```typescript * const engine = createConsensusEngine({ * defaultTimeout: 60000, * maxActiveProposals: 10, * }); * ``` */ declare function createConsensusEngine(config?: Partial, logger?: ILogger): ConsensusEngine; /** * Multi-Round Voting Protocol Implementation * * Implements a structured 3-round voting protocol for multi-agent code review * based on research showing 91.7-100% success rates vs 78% single-agent baseline. * * @module consensus/voting-protocol * (Source: Issue #100, arXiv:2512.21352 - Multi-Agent Committees) * (Source: arXiv:2509.23055 - Sycophancy Prevention) */ /** * Multi-round voting protocol for code review. */ declare class VotingProtocol implements IVotingProtocol { private readonly sessions; private readonly logger; constructor(customLogger?: ILogger); /** * Create a new voting session with a committee. */ createSession(topic: string, committee: string[], config?: Partial): VotingSession; /** * Start the analysis round (Round 1). */ startAnalysisRound(sessionId: string): Promise; /** * Submit findings from an agent during analysis. */ submitFindings(sessionId: string, agentId: string, findings: AgentFinding[]): Promise; /** * Start the deliberation round (Round 2). */ startDeliberationRound(sessionId: string): Promise; /** * Vote on findings during deliberation. */ voteOnFinding(sessionId: string, vote: FindingVote): Promise; /** * Start the consensus round (Round 3). */ startConsensusRound(sessionId: string): Promise; /** * Submit final vote during consensus. */ submitFinalVote(sessionId: string, agentId: string, vote: Vote): Promise; /** * Get the final result. */ getResult(sessionId: string): Promise; /** * Detect sycophancy patterns. */ detectSycophancy(sessionId: string): SycophancyReport; /** * Get the current session state. */ getSession(sessionId: string): VotingSession | undefined; private getSessionOrThrow; private validateSessionActive; private getCurrentRound; private buildFinalResult; } /** * Create a voting protocol instance. */ declare function createVotingProtocol(customLogger?: ILogger): VotingProtocol; /** Options for WeightedVoting constructor. */ interface WeightedVotingOptions { /** Configuration for voting thresholds and weights. */ config?: Partial; /** Optional event bus for Byzantine detection events (Issue #218). */ eventBus?: ICollaborationEventBus; /** Whether to emit Byzantine detection events (default: true if eventBus provided). */ emitEvents?: boolean; } /** * nexus-agents/consensus - Weighted Byzantine Voting Implementation * * Implements CP-WBFT (arXiv:2511.10400) for weighted Byzantine fault-tolerant voting. * Agent votes are weighted by historical reliability with automatic trust calibration. * * @module consensus/weighted-voting * (Source: Issue #103, arXiv:2511.10400 - CP-WBFT) */ /** * Weighted Byzantine voting implementation. * Implements CP-WBFT pattern for fault-tolerant multi-agent consensus. */ declare class WeightedVoting implements IWeightedVoting { private readonly records; private readonly config; private readonly eventBus; private readonly emitEvents; constructor(options?: WeightedVotingOptions); calculateWeight(agentId: string): number; updatePerformance(agentId: string, outcome: TaskOutcomeStatus): void; weightedConsensus(votes: ReadonlyMap): WeightedConsensusResult; registerAgent(agentId: string): void; getAgentRecord(agentId: string): WeightedAgentRecord | undefined; flagByzantine(agentId: string, reason: string): void; getAllRecords(): readonly WeightedAgentRecord[]; canVote(agentId: string): boolean; recalibrateWeights(): void; private countVotes; private logConsensusResult; private emitWeightChange; private emitAgentFlaggedEvent; private excludeAgent; private detectByzantinePatterns; private detectContrarianByzantine; private emitContrarianPattern; private detectCollusionPattern; private emitCollusionEvents; } /** Create a weighted voting instance. */ declare function createWeightedVoting(options?: WeightedVotingOptions): IWeightedVoting; /** * nexus-agents/consensus - Correlation Tracker * * Tracks voting history and computes pairwise correlations between agents. * Used by higher-order voting methods to account for agent dependencies. * * @module consensus/correlation-tracker * (Source: Issue #333) */ /** * Correlation tracker implementation. * Records voting history and computes pairwise agent correlations. * * Memory bounded: uses FIFO eviction when maxObservationsPerAgent or maxProposals limits reached. */ declare class CorrelationTracker implements ICorrelationTracker { private readonly config; private readonly observations; private readonly modelPartitions; private readonly agentProposals; /** Ordered list of proposal IDs for FIFO eviction */ private readonly proposalOrder; private cachedSubsets; constructor(config?: Partial); setCurrentModelPins(modelPins: ReadonlyMap): void; recordVote(agentId: string, vote: Vote, outcome: 'approved' | 'rejected', context?: CorrelationRecordContext): void; recordProposalVotes(proposalId: string, votes: ReadonlyMap, outcome: 'approved' | 'rejected', context?: CorrelationRecordContext): void; computeCorrelationMatrix(): CorrelationMatrix; getCorrelation(agentA: string, agentB: string): CorrelationCoefficient | undefined; identifyIndependentSubsets(): readonly IndependentSubset[]; hasSufficientData(agentIds: readonly string[]): boolean; getStats(): CorrelationTrackerStats; clear(): void; /** * Evict oldest proposals when maxProposals limit is reached. * Also cleans up agentProposals entries for evicted proposals. */ private evictOldProposalsIfNeeded; private storeObservation; private storeAgentProposal; private updatePairwiseCorrelations; private getTrackedAgents; private getActivePairwiseHistory; private invalidateCache; } /** * Creates a new correlation tracker instance. */ declare function createCorrelationTracker(config?: Partial): ICorrelationTracker; /** * nexus-agents/consensus - Higher-Order Voting Implementation * * Implements Opinion-Wise (OW) and Independent Subset Partition (ISP) voting * methods that account for correlations between agent opinions. * * Traditional voting assumes independence between voters. Higher-order voting * uses Bayesian-optimal aggregation that handles correlated agents better, * BUT NOTE (#4701): `calculateOutcome` — the `IVotingStrategy` entry point the * `ConsensusEngine` calls — uses `aggregateSimpleInternal` and ignores weights. * `aggregateWithCorrelation` is reached only via `runHigherOrderVoting`, whose * `posteriorApproval` feeds contrarian escalation, not the verdict. So selecting * `higher_order` does not currently buy a correlation-weighted approve/reject. * resulting in more accurate consensus decisions. * * @module consensus/higher-order-voting * (Source: Issue #333) */ /** Options for creating OWVoting instance. */ interface OWVotingOptions { readonly config?: Partial; /** * Algorithm label this instance reports (#3168). Defaults to `simple_majority` * for backward compatibility; `HigherOrderVotingStrategy` sets `opinion_wise`. * Keeps the label consistent whether constructed directly or via a factory. */ readonly algorithm?: ConsensusAlgorithm; /** * Correlation tracker this instance uses when {@link OWVoting.aggregate} is * called WITHOUT a per-call tracker (#3173). Injecting here lets higher-order * voting be reused as a building block (autonomous agents, test harnesses, * custom pipelines) without coupling to the MCP tool's process-wide singleton * or threading the tracker through every call. Omit it to keep the singleton * model — the MCP consensus path injects/passes its persistent tracker. */ readonly tracker?: ICorrelationTracker; } /** * Opinion-Wise higher-order voting implementation. * Uses Bayesian aggregation with correlation awareness. */ declare class OWVoting implements IHigherOrderVoting, IVotingStrategy { readonly algorithm: ConsensusAlgorithm; private readonly config; /** #3173: tracker used when `aggregate` is called without a per-call one. */ private readonly injectedTracker; constructor(options?: OWVotingOptions); /** IVotingStrategy implementation for integration with ConsensusEngine. */ calculateOutcome(votes: Map, _weights?: Map): VotingOutcome; aggregateWithCorrelation(votes: ReadonlyMap, correlationMatrix: CorrelationMatrix): HigherOrderVotingResult; estimateCorrelation(tracker: ICorrelationTracker): CorrelationMatrix; computeISP(votes: ReadonlyMap, independentSubsets: readonly IndependentSubset[]): HigherOrderVotingResult; aggregate(votes: ReadonlyMap, tracker?: ICorrelationTracker): HigherOrderVotingResult; /** Core aggregation against a resolved tracker (#3173 — extracted from aggregate). */ private aggregateWith; getConfig(): HigherOrderVotingConfig; private aggregateSimpleInternal; private toVotingOutcome; } /** Creates a new OWVoting instance. */ declare function createOWVoting(options?: OWVotingOptions): IHigherOrderVoting; /** * Higher-order voting strategy for integration with VotingStrategyFactory. * Wraps OWVoting to provide IVotingStrategy interface. */ declare class HigherOrderVotingStrategy extends OWVoting implements IVotingStrategy { constructor(options?: OWVotingOptions); } /** Creates a higher-order voting strategy for use with ConsensusEngine. */ declare function createHigherOrderVotingStrategy(options?: OWVotingOptions): HigherOrderVotingStrategy; /** * Adapter resolution for a voter panel, and the documented no-adapter exit * (Issue #280): simulate when the caller explicitly allowed it, otherwise * throw. * * Split out of `voter-agents.ts` (#5578), which was at its 400-line cap. * @module cli/voter-adapter-resolve */ /** * Error thrown when no adapter is available and simulation is disabled. */ declare class NoAdapterError extends Error { constructor(message: string); } /** * nexus-agents voter agents * * Real LLM-powered voter agents for consensus voting. * Replaces simulated voting with actual agent execution that * analyzes proposals. * * (Source: Issue #226, Sprint #229) * (Updated: Issue #280 - Fixed timeout handling, removed simulation fallback) * (Refactored: Issue #285 - Extracted response and execution utilities) * * File structure: * - voter-prompts.ts: System prompts for each voter role * - voter-response.ts: Response parsing and validation * - voter-execution.ts: Execution utilities (timeout, retry, result creation) * - voter-agents.ts: Main API (this file) */ interface VoterAgentOptions { /** Logger instance */ readonly logger?: ILogger; /** Model adapter to use (auto-selected if not provided) */ readonly adapter?: IModelAdapter; /** Timeout per vote in milliseconds (default: 120000, override via NEXUS_VOTE_TIMEOUT_MS) */ readonly timeoutMs?: number; /** Maximum retries per vote (default: 2) */ readonly maxRetries?: number; /** Whether to allow simulation fallback (default: false per Issue #280) */ readonly allowSimulation?: boolean; /** Delay between launching each agent vote to prevent rate limiting (default: 1000ms). Set to 0 to disable. */ readonly interAgentDelayMs?: number; } /** * Options for collecting votes from multiple agents. */ interface CollectRealVotesOptions extends VoterAgentOptions { /** Repository checkout used by every panel seat. */ readonly workspace?: string | undefined; readonly workspaceSha?: string | undefined; /** Voter roles to include */ readonly roles: readonly VoterRole[]; /** Proposal text */ readonly proposal: string; /** Use simulation mode (explicit opt-in only) */ readonly simulate?: boolean; /** * In-process gateway model adapters (#4040) — one per discovered gateway model. * When provided (and no explicit `adapter` override), voters route through these * HTTP adapters instead of shelling out to CLIs: roles are round-robined across * them for per-role model diversity, the API key stays in-process (no subprocess * env-forwarding), and the nested-spawn class (#4033) cannot occur. Empty/omitted * ⇒ the CLI round-robin path is used (unchanged). */ readonly gatewayAdapters?: readonly IModelAdapter[] | undefined; /** Named alternatives for a multi-option proposal (#4472); each voter picks one. */ readonly declaredOptions?: readonly string[] | undefined; /** * The project the panel is judging, already resolved and validated by the * caller (#6110). Reaches every seat's system prompt. Absent ⇒ `nexus-agents`. */ readonly project?: string | undefined; /** * Cancellation for an in-flight panel (#5393). Stops LAUNCHING voters that * have not started; votes already in flight settle. Absent changes nothing. */ readonly signal?: AbortSignal | undefined; /** * Per-seat progress callback (#6162): invoked with each seat's result as it * settles, on every pass (first, fallback, retry). The async-job heartbeat * for vote bodies; absent changes nothing. */ readonly onVoteCollected?: ((vote: AgentVoteResult) => void) | undefined; /** * Delay before the per-role retry of errored voters (#5578). Defaults to * {@link DEFAULT_ERRORED_ROLE_BACKOFF_MS}; 0 disables the wait, which is what * tests want. The retry itself is not optional — the panel applies it under * every error policy, per the #5578 design panel (option b, 6 of 6). */ readonly erroredRoleBackoffMs?: number | undefined; /** * Seats already assigned by {@link assignPanelSeats} (#6003): a caller that * must know the panel's models BEFORE the vote (the pr_review budget reads * their windows) resolves the seats once and hands them back, so the panel * runs on exactly what it was budgeted for. Ignored when `adapter` is set. */ readonly roleAdapters?: ReadonlyMap | undefined; } declare function collectRealVotes(options: CollectRealVotesOptions): Promise; /** * nexus-agents/agents - OrchestrationObserver Helper Functions * * Pure helper functions for OrchestrationObserver that don't depend on class state. * Extracted to reduce main class file size and improve testability. * * @module agents/observability/orchestration-observer-helpers */ /** * Extracts a string field from a payload object safely. * * @param payload - The payload object to extract from * @param field - The field name to extract * @returns The string value or empty string if not found/invalid */ declare function extractStringField(payload: Record, field: string): string; /** * Extracts a number field from a payload object safely. * * @param payload - The payload object to extract from * @param field - The field name to extract * @param defaultValue - Default value if not found * @returns The number value or default if not found/invalid */ declare function extractNumberField(payload: Record, field: string, defaultValue?: number): number; /** * Extracts a boolean field from a payload object safely. * * @param payload - The payload object to extract from * @param field - The field name to extract * @returns The boolean value (defaults to false if not found/invalid) */ declare function extractBooleanField(payload: Record, field: string): boolean; /** * Extracts a string array field from a payload object safely. * * @param payload - The payload object to extract from * @param field - The field name to extract * @returns The string array or empty array if not found/invalid */ declare function extractStringArrayField(payload: Record, field: string): string[]; /** * Extracts session ID from event object or payload. * * @param event - The domain event * @param payload - The event payload * @returns The session ID or empty string if not found */ declare function extractSessionId(event: DomainEvent, payload: Record): string; /** * Creates initial session metrics with default values. * * @param sessionId - The session ID * @returns A new SessionMetrics object with initial values */ declare function createInitialSessionMetrics(sessionId: string): SessionMetrics; /** * Creates initial token usage with zero values. * * @returns A new SessionTokenTotals object with zero values */ declare function createInitialTokenUsage(): SessionTokenTotals; /** * Creates initial cost metrics with zero values. * * @returns A new CostMetrics object with zero values */ declare function createInitialCostMetrics(): CostMetrics; /** * Creates a new TrackedAgent object with initial values. * * @param agentId - The agent ID * @param state - The initial agent state * @param role - The agent role (defaults to 'unknown') * @param currentTask - Optional current task description * @returns A new TrackedAgent object */ declare function createTrackedAgent(agentId: string, state: AgentState$1, role?: string, currentTask?: string): TrackedAgent; /** * Calculates routing distribution from routing history. * * @param routingHistory - The routing decision history * @returns A record mapping CLI names to counts */ declare function calculateRoutingDistribution(routingHistory: readonly RoutingDecision$2[]): Record; /** * Aggregates token and cost totals from session metrics. * * @param sessionMetrics - Iterable of session metrics * @returns Object containing total tokens and total cost */ declare function calculateMetricsTotals(sessionMetrics: Iterable): { totalTokens: number; totalCost: number; }; /** * Counts active sessions (sessions without a completedAt timestamp). * * @param sessionMetrics - Iterable of session metrics * @returns The count of active sessions */ declare function countActiveSessions(sessionMetrics: Iterable): number; /** * Finds the first active session (no completedAt) from metrics. * * @param sessionMetrics - Iterable of session metrics * @returns The first active session or undefined */ declare function findActiveSession(sessionMetrics: Iterable): SessionMetrics | undefined; /** * Identifies session IDs to remove based on max history limit. * Returns oldest sessions first. * * @param sessions - Array of [sessionId, metrics] entries * @param maxSessions - Maximum sessions to keep * @returns Array of session IDs to remove */ declare function identifySessionsToRemove(sessions: Array<[string, SessionMetrics]>, maxSessions: number): string[]; /** * Calculates the cost for token usage based on rate. * * @param tokens - Token usage to calculate cost for * @param ratePerThousand - Cost rate per 1000 tokens * @returns The calculated cost in USD */ declare function calculateTokenCost(tokens: SessionTokenTotals, ratePerThousand: number): number; /** A tracked task/issue. */ interface TrackedTask { /** Backend-specific ID (issue number or local ID). */ readonly id: string; readonly title: string; readonly status: 'open' | 'in_progress' | 'closed'; readonly url?: string | undefined; } /** Task tracker interface — create, update, comment. */ interface ITaskTracker { createTask(title: string, body: string): Promise; updateStatus(taskId: string, status: TrackedTask['status']): Promise; postComment(taskId: string, comment: string): Promise; } /** * nexus-agents/benchmarks - Memory Benchmark Helper Functions * * Pure helper functions for memory benchmarks: test data generation, * metrics calculation, and comparison utilities. * * @module benchmarks/memory-benchmarks-helpers */ /** * Operation comparison result. */ interface OperationComparison { readonly operation: string; readonly datasetSize: number; readonly baselineP95: number; readonly currentP95: number; readonly latencyChangePercent: number; readonly baselineThroughput: number; readonly currentThroughput: number; readonly throughputChangePercent: number; readonly improved: boolean; } /** * Benchmark comparison result. */ interface BenchmarkComparison { readonly baseline: string; readonly current: string; readonly comparisons: readonly OperationComparison[]; readonly overallLatencyChangePercent: number; readonly meetsMemZeroTarget: boolean; } /** * Memory benchmark configuration extending base benchmark config. */ interface MemoryBenchmarkConfig extends BenchmarkConfig { /** Size of content in bytes. */ readonly contentSizeBytes: number; /** Number of tags per entry. */ readonly tagsPerEntry: number; /** Search query patterns. */ readonly searchPatterns: readonly string[]; } /** * Format comparison results as a human-readable string. */ declare function formatComparisonResults(comparison: BenchmarkComparison): string; /** * nexus-agents/benchmarks - Token Usage Benchmark * * Measures token savings from memory-optimized retrieval vs baseline * full-context approach. Validates Mem0 claim of 90% token savings. * * @module benchmarks/token-benchmark * (Source: Issue #462, arXiv:2504.19413) */ /** * Token benchmark result comparing baseline vs memory-optimized retrieval. */ interface TokenBenchmarkResult { readonly datasetSize: number; readonly baseline: TokenMetrics; readonly optimized: TokenMetrics; readonly savingsPercent: number; readonly meetsMemZeroTarget: boolean; /** * Search calls that returned an error (#5689). When every search failed the * "optimized" context is empty for the wrong reason, so `savingsPercent` is * reported as 0 and the target as not met — not as a 100% saving. */ readonly searchesFailed: number; } /** * Estimate token count from text content. */ declare function estimateTokens(text: string): number; /** * Calculate token metrics for a set of entries. */ declare function calculateTokenMetrics(entries: readonly { content: string; }[], queryCount: number): TokenMetrics; /** * Run token savings benchmark. * * Compares baseline (all entries in context) vs optimized * (only relevant entries from search) token usage. */ declare function runTokenBenchmark(backend: IContextMemoryBackend, config?: Partial): Promise; /** * nexus-agents/benchmarks - Benchmark Runner * * Utilities for running benchmarks and collecting metrics. * * @module benchmarks/benchmark-runner * (Source: Issue #156, Mem0 metrics validation) */ /** * Sample collector for latency measurements. */ declare class LatencySampler { private readonly samples; private readonly startTimes; /** * Start timing an operation. */ start(id: string): void; /** * End timing and record the sample. */ end(id: string): number; /** * Record a sample directly. */ record(durationMs: number): void; /** * Calculate latency metrics from collected samples. */ getMetrics(): LatencyMetrics; /** * Reset collected samples. */ reset(): void; } /** * Benchmark operation function type. */ type BenchmarkOperation = () => Promise | void; /** * Run a single operation benchmark. */ declare function runOperationBenchmark(operation: string, datasetSize: number, fn: BenchmarkOperation, config?: Partial): Promise; /** * Get benchmark environment information. */ declare function getBenchmarkEnvironment(): BenchmarkEnvironment; /** * Create benchmark summary from operations. */ declare function createBenchmarkSummary(operations: readonly OperationBenchmark[], config?: Partial): BenchmarkSummary; /** * Format benchmark results for console output. */ declare function formatBenchmarkResults(result: BenchmarkSuiteResult): string; /** * nexus-agents/benchmarks - Memory Backend Benchmarks * * Benchmarks for memory backend operations (store, retrieve, search, prune). * Validates Mem0 claimed metrics: 91% lower p95 latency, 90% token savings. * * @module benchmarks/memory-benchmarks * (Source: Issue #156, arXiv:2504.19413) */ /** * Default memory benchmark configuration. */ declare const DEFAULT_MEMORY_BENCHMARK_CONFIG: MemoryBenchmarkConfig; /** * Run all memory backend benchmarks. */ declare function runMemoryBenchmarks(backend: IContextMemoryBackend, name: string, config?: Partial): Promise; /** * Compare benchmarks between two backends. */ declare function compareBenchmarks(baseline: BenchmarkSuiteResult, current: BenchmarkSuiteResult): BenchmarkComparison; /** * nexus-agents/benchmarks - Consolidation Benchmark * * Benchmarks memory consolidation operations: promotion pipeline * (session → belief → agentic) and decay/eviction performance. * * @module benchmarks/consolidation-benchmark * (Source: Issue #462, arXiv:2504.19413) */ /** * Consolidation operation that can be benchmarked. */ interface ConsolidationOperation { readonly name: string; readonly run: () => Promise; } /** * Consolidation benchmark result. */ interface ConsolidationBenchmarkResult { readonly operations: readonly OperationBenchmark[]; readonly timestamp: string; } /** * Run consolidation benchmarks on a set of operations. * * Measures latency and throughput of promotion, decay, and eviction * operations that maintain memory health over time. */ declare function runConsolidationBenchmark(operations: readonly ConsolidationOperation[], config?: Partial): Promise; /** * Create a promotion operation from a callback. */ declare function createPromotionOp(name: string, promoteFn: () => Promise): ConsolidationOperation; /** * Create a decay operation from a callback. */ declare function createDecayOp(name: string, decayFn: () => Promise): ConsolidationOperation; /** * nexus-agents/benchmarks - Benchmark Report Generator * * Generates structured JSON reports from benchmark results. * Validates results against Mem0 claimed metrics. * * @module benchmarks/benchmark-report * (Source: Issue #462, arXiv:2504.19413) */ /** * Mem0 claimed targets from arXiv:2504.19413. */ declare const MEM0_TARGETS: { readonly latencyReductionPercent: 91; readonly tokenSavingsPercent: 90; readonly qualityImprovementPercent: 26; }; /** * Validation result for a single Mem0 claim. */ interface ClaimValidation { readonly claim: string; readonly targetPercent: number; readonly actualPercent: number; readonly met: boolean; readonly delta: number; } /** * Complete benchmark report. */ interface BenchmarkReport { readonly version: string; readonly timestamp: string; readonly suite: BenchmarkSuiteResult | null; readonly comparison: BenchmarkComparison | null; readonly tokenResults: readonly TokenBenchmarkResult[]; readonly consolidation: ConsolidationBenchmarkResult | null; readonly mem0Validation: readonly ClaimValidation[]; readonly overallPass: boolean; } /** * Options for generating a benchmark report. */ interface ReportOptions { readonly suite?: BenchmarkSuiteResult; readonly comparison?: BenchmarkComparison; readonly tokenResults?: readonly TokenBenchmarkResult[]; readonly consolidation?: ConsolidationBenchmarkResult; } /** * Generate a complete benchmark report. */ declare function generateBenchmarkReport(options: ReportOptions): BenchmarkReport; /** * Format a benchmark report as a human-readable string. */ declare function formatBenchmarkReport(report: BenchmarkReport): string; /** * nexus-agents/benchmarks - Adapter Latency Benchmark * * Measures latency overhead of CLI subprocess invocation vs direct API adapter calls. * Supports both mock adapters (CI) and real adapters (local manual runs). * * @module benchmarks/adapter-latency-benchmark * (Source: Issue #694, CLI subprocess vs API adapter latency) */ /** * Configuration for adapter latency benchmarks. */ interface AdapterLatencyConfig { /** Number of warmup iterations (not measured). */ readonly warmupIterations: number; /** Number of measured iterations per scenario. */ readonly measurementIterations: number; /** Timeout per operation in milliseconds. */ readonly timeoutMs: number; } /** * Default adapter latency benchmark configuration. */ declare const DEFAULT_ADAPTER_LATENCY_CONFIG: AdapterLatencyConfig; /** * A single scenario to benchmark. */ interface LatencyScenario { /** Scenario name (e.g., 'simple-prompt', 'complex-prompt'). */ readonly name: string; /** Input prompt content. */ readonly content: string; /** Optional system prompt. */ readonly systemPrompt?: string; /** Max tokens for generation. */ readonly maxTokens?: number; } /** * Default scenarios matching issue #694 requirements. */ declare const DEFAULT_SCENARIOS: readonly LatencyScenario[]; /** * Result for a single adapter + scenario combination. */ interface AdapterScenarioResult { /** CLI adapter name. */ readonly adapterName: CliName; /** Transport type used. */ readonly transport: CliTransport; /** Scenario name. */ readonly scenario: string; /** Latency metrics from measured iterations. */ readonly latency: LatencyMetrics; /** Number of successful iterations. */ readonly successCount: number; /** Number of failed iterations. */ readonly failureCount: number; /** Error messages from failures. */ readonly errors: readonly string[]; } /** * Complete adapter latency benchmark result. */ interface AdapterLatencyResult { /** Timestamp of the benchmark run. */ readonly timestamp: string; /** Environment information. */ readonly environment: BenchmarkEnvironment; /** Per-adapter, per-scenario results. */ readonly results: readonly AdapterScenarioResult[]; /** Total benchmark duration in milliseconds. */ readonly totalDurationMs: number; } /** * Run latency benchmarks across adapters and scenarios. */ declare function runAdapterLatencyBenchmark(adapters: readonly ICliAdapter[], scenarios?: readonly LatencyScenario[], config?: Partial): Promise; /** * Format adapter latency results as a markdown report. */ declare function formatAdapterLatencyReport(result: AdapterLatencyResult): string; /** * Convert adapter latency results to BenchmarkSuiteResult for compatibility * with the generic formatBenchmarkResults() function. */ declare function toSuiteResult(result: AdapterLatencyResult): BenchmarkSuiteResult; /** * BenchmarkAdapter — public contract for benchmark integrations. * * Standalone benchmark repos (nexus-eval-swebench, nexus-eval-safety, etc.) * implement this interface. nexus-agents core exposes it so any benchmark * runner can plug into the same CLI / reporting / CI surface. * * (Source: Issue #1960 — extract benchmark suites into standalone repos) * * @module benchmarks/adapter */ /** * High-level summary of a benchmark run, CLI-printable and JSON-serializable. * Benchmarks that need extra dimensions attach them via `metadata`. */ interface BenchmarkRunSummary { /** Benchmark name (e.g., 'swe-bench'). */ readonly name: string; /** Variant, if applicable (e.g., 'lite', 'verified'). */ readonly variant: string | undefined; /** Total instances attempted. */ readonly total: number; /** Instances whose evaluation reported pass. */ readonly passed: number; /** passed / total, in [0, 1]. */ readonly passRate: number; /** Wall-clock runtime in milliseconds. */ readonly runTimeMs: number; /** Benchmark-specific extras (dataset hash, model IDs, etc.). */ readonly metadata: Record; } /** * Execution context handed to a runner. * * Keep this interface narrow — benchmarks that need more (e.g. access to * specific adapters) should take those as constructor args, not widen this. */ interface BenchmarkRunContext { /** Per-instance timeout budget in milliseconds. */ readonly timeoutMs: number; /** Emit progress updates for long-running benchmarks. */ readonly onProgress?: (completed: number, total: number, label?: string) => void; /** Optional abort signal for cancellation. */ readonly signal?: AbortSignal; } /** * Contract every benchmark implementation fulfills. * * Type parameters: * - `TInstance`: one task / problem in the benchmark (e.g., a SWE-bench issue) * - `TPrediction`: the solver's output (e.g., a proposed patch) * - `TEvalResult`: the evaluator's verdict (e.g., patch applied + tests passed) * * A correct implementation composes as: * `loadInstances -> runInstance(each) -> evaluate(each) -> summarize` * * @example * ```ts * class SweBenchAdapter implements BenchmarkAdapter { * readonly name = 'swe-bench'; * readonly variant = 'lite'; * async loadInstances(config) { ... } * async runInstance(inst, ctx) { ... } * async evaluate(inst, pred) { ... } * summarize(results) { ... } * } * ``` */ interface BenchmarkAdapter { /** Stable identifier (e.g., 'swe-bench', 'humaneval'). Used in CLI routing and reporting. */ readonly name: string; /** Optional variant within a benchmark family (e.g., 'lite' vs 'verified'). */ readonly variant?: string; /** Load the benchmark task set from disk/remote. Runs once per invocation. */ loadInstances(config: Record): Promise; /** Execute the solver on one instance. No evaluation here — just generate the prediction. */ runInstance(instance: TInstance, ctx: BenchmarkRunContext): Promise; /** Evaluate a prediction against ground truth. Returns a benchmark-specific verdict. */ evaluate(instance: TInstance, prediction: TPrediction): Promise; /** Determine whether a verdict counts as pass. Keeps pass/fail semantics localized. */ isPass(result: TEvalResult): boolean; /** Aggregate instance results into a summary. Should be pure + deterministic. */ summarize(results: readonly TEvalResult[], runTimeMs: number): BenchmarkRunSummary; } /** Default no-op progress handler. */ declare const NOOP_PROGRESS: BenchmarkRunContext['onProgress']; /** * Runs a BenchmarkAdapter end-to-end: load → run → evaluate → summarize. * * Handles concurrency, timeouts, progress, and partial failure so each * adapter doesn't reinvent the same harness. * * @module benchmarks/orchestrator */ interface BenchmarkOrchestratorOptions { /** Max parallel `runInstance` calls. Default 1 (serial). */ readonly concurrency?: number; /** Per-instance timeout in ms. Default 300_000 (5 min). */ readonly instanceTimeoutMs?: number; /** Limit instances evaluated (useful for smoke runs). */ readonly limit?: number; /** Progress callback. */ readonly onProgress?: BenchmarkRunContext['onProgress']; /** Abort the whole run. */ readonly signal?: AbortSignal; } /** * Execute one adapter end-to-end. Returns the adapter-produced summary. * * Behavioral notes: * - An instance failure (either runInstance or evaluate throws) is captured * as a failure count in summary metadata; the run continues. * - Timeouts cancel via AbortController; adapters should honor `ctx.signal`. */ declare function runBenchmark(adapter: BenchmarkAdapter, config: Record, options?: BenchmarkOrchestratorOptions): Promise; /** * TaskContract + PlanContract — V2 Pipeline OS Core Types * * Unified task lifecycle and execution plan types with Zod validation. * These replace the 5+ task representations in V1 with a single contract. * * @see docs/v2/api-contracts.md * @see docs/v2/adrs/ADR-0002-unified-task-plan-artifact.md * @module pipeline/task-contract */ /** All valid task lifecycle statuses. */ declare const TASK_STATUSES: readonly ["intake", "clarifying", "planning", "approved", "executing", "validating", "done", "failed"]; /** All valid pipeline stage types. */ declare const STAGE_TYPES: readonly ["analyze", "route", "execute", "validate", "aggregate", "gate"]; /** All valid artifact types. */ declare const ARTIFACT_TYPES: readonly ["code", "review", "plan", "test", "report", "vote", "spec", "analysis"]; type TaskStatus = (typeof TASK_STATUSES)[number]; type StageType = (typeof STAGE_TYPES)[number]; type ArtifactType = (typeof ARTIFACT_TYPES)[number]; /** Reference to an artifact by ID and type. */ declare const ArtifactRefSchema: z.ZodObject<{ id: z.ZodString; type: z.ZodEnum<{ code: "code"; analysis: "analysis"; test: "test"; spec: "spec"; review: "review"; report: "report"; plan: "plan"; vote: "vote"; }>; }, z.core.$strip>; /** Unified task lifecycle contract. */ declare const TaskContractSchema: z.ZodObject<{ id: z.ZodString; description: z.ZodString; status: z.ZodEnum<{ failed: "failed"; planning: "planning"; done: "done"; approved: "approved"; executing: "executing"; intake: "intake"; clarifying: "clarifying"; validating: "validating"; }>; analysis: z.ZodObject<{ complexity: z.ZodString; taskType: z.ZodString; ambiguityScore: z.ZodNumber; }, z.core.$strip>; constraints: z.ZodObject<{ time: z.ZodOptional; quality: z.ZodOptional; scope: z.ZodArray; }, z.core.$strip>; requiredCapabilities: z.ZodObject<{ tools: z.ZodArray; experts: z.ZodArray; }, z.core.$strip>; capabilityGaps: z.ZodObject<{ available: z.ZodObject<{ tools: z.ZodArray; experts: z.ZodArray; }, z.core.$strip>; gaps: z.ZodArray; allSatisfied: z.ZodBoolean; gapsMeasured: z.ZodBoolean; }, z.core.$strip>; parentId: z.ZodOptional; artifacts: z.ZodArray; }, z.core.$strip>>; metadata: z.ZodRecord; createdAt: z.ZodNumber; updatedAt: z.ZodNumber; completedAt: z.ZodOptional; error: z.ZodOptional; }, z.core.$strip>; /** Pipeline stage specification. */ declare const StageSpecSchema: z.ZodObject<{ id: z.ZodString; type: z.ZodEnum<{ analyze: "analyze"; validate: "validate"; aggregate: "aggregate"; route: "route"; gate: "gate"; execute: "execute"; }>; pluginId: z.ZodString; inputArtifacts: z.ZodArray; outputArtifacts: z.ZodArray; dependencies: z.ZodArray; config: z.ZodRecord; preferredCli: z.ZodOptional; maxRetries: z.ZodOptional; timeoutMs: z.ZodOptional; }, z.core.$strip>; /** * Policy gate inserted between pipeline stages. * * NOTE on enforcement (#4019): the gate's effective enforcement mode is resolved * SOLELY by the runtime enforcement bundle — `GatePolicyEnforcement.mode` (or * `NEXUS_POLICY_GATE_MODE`, warn-by-default per #3177). There is intentionally NO * per-gate fail-action field here: the former `onFail` enum was inert (consumed * nowhere — verified) and required every gate to declare a fail action that did * nothing, so authoring `onFail:'block'` gave a false sense of enforcement. * Removed (7/0 higher_order vote) so the contract cannot promise enforcement the * runtime won't deliver. Set the enforcement mode to make a gate block. */ declare const PolicyGateSpecSchema: z.ZodObject<{ id: z.ZodString; afterStage: z.ZodString; beforeStage: z.ZodString; rules: z.ZodArray; }, z.core.$strip>; /** Cost estimate for a pipeline execution plan. */ declare const CostEstimateSchema: z.ZodObject<{ totalTokensIn: z.ZodNumber; totalTokensOut: z.ZodNumber; estimatedCostUsd: z.ZodNumber; modelCalls: z.ZodNumber; }, z.core.$strip>; /** Execution plan contract. */ declare const PlanContractSchema: z.ZodObject<{ taskId: z.ZodString; stages: z.ZodArray; pluginId: z.ZodString; inputArtifacts: z.ZodArray; outputArtifacts: z.ZodArray; dependencies: z.ZodArray; config: z.ZodRecord; preferredCli: z.ZodOptional; maxRetries: z.ZodOptional; timeoutMs: z.ZodOptional; }, z.core.$strip>>; policyGates: z.ZodArray; }, z.core.$strip>>; estimatedCost: z.ZodObject<{ totalTokensIn: z.ZodNumber; totalTokensOut: z.ZodNumber; estimatedCostUsd: z.ZodNumber; modelCalls: z.ZodNumber; }, z.core.$strip>; approvalRequired: z.ZodBoolean; maxIterations: z.ZodNumber; timeoutMs: z.ZodNumber; }, z.core.$strip>; type TaskContract = z.infer; type PlanContract = z.infer; type StageSpec = z.infer; type PolicyGateSpec = z.infer; type CostEstimate = z.infer; type ArtifactRef = z.infer; /** * Plugin System Types — V2 Pipeline OS (Issue #911, Phase 3-1) * * Defines the plugin manifest, plugin interface, stage context, * stage result, and plugin registry interface. * * @see docs/v2/05-plugin-system-spec.md * @module pipeline/plugin-types */ /** All valid plugin trust levels. */ declare const PLUGIN_TRUST_LEVELS: readonly ["core", "standard", "experimental", "external"]; type PluginTrustLevel = (typeof PLUGIN_TRUST_LEVELS)[number]; /** Schema for plugin manifests. */ declare const PluginManifestSchema: z.ZodObject<{ id: z.ZodString; version: z.ZodString; description: z.ZodString; stages: z.ZodArray>; requiredCapabilities: z.ZodArray; trustLevel: z.ZodEnum<{ standard: "standard"; external: "external"; experimental: "experimental"; core: "core"; }>; experimental: z.ZodBoolean; }, z.core.$strip>; /** Schema for stage execution results. */ declare const StageResultSchema: z.ZodObject<{ success: z.ZodBoolean; outputArtifacts: z.ZodArray; }, z.core.$strip>>; metadata: z.ZodRecord; error: z.ZodOptional; }, z.core.$strip>; /** Plugin manifest declaring identity and capabilities. */ type PluginManifest = z.infer; /** Result of a plugin stage execution. */ type StageResult = z.infer; /** * Runtime context passed to plugins during stage execution. * Plugins communicate only via artifacts and events. */ interface StageContext { /** Abort signal for cancellation. */ readonly signal: AbortSignal; /** Task contract for reference (read-only). */ readonly task: Readonly; /** Stage configuration from the plan. */ readonly config: Record; } /** * Plugin interface — every stage implementation must conform. * * Plugins are the ONLY way stage logic runs. * They communicate via ArtifactStore and EventBus (injected via context). */ interface PipelinePlugin { /** Manifest declaring this plugin's identity and capabilities. */ readonly manifest: PluginManifest; /** * Execute a pipeline stage. * @param stage - The stage specification from the PlanContract * @param context - Runtime context with abort signal and task * @returns Stage result with output artifacts */ execute(stage: StageSpec, context: StageContext): Promise; /** * Validate plugin configuration at registration time. * Called once when the plugin is registered, not per-execution. */ validateConfig(config: unknown): Result; /** Optional lifecycle hook — called when plugin is loaded. */ onLoad?(): Promise; /** Optional lifecycle hook — called when plugin is unloaded. */ onUnload?(): Promise; } /** Validation error from plugin config validation. */ interface ValidationError { readonly message: string; readonly field?: string; } /** Registration error when adding a plugin to the registry. */ type RegistrationError = { readonly type: 'duplicate_id'; readonly pluginId: string; } | { readonly type: 'invalid_manifest'; readonly message: string; } | { readonly type: 'missing_capability'; readonly capability: string; } | { readonly type: 'validation_failed'; readonly message: string; } | { readonly type: 'registry_frozen'; }; /** * Plugin registry — manages plugin lifecycle and resolution. * * Registry is frozen after startup — no runtime registration. */ interface IPluginRegistry { /** * Register a plugin. Validates manifest and config. * Returns error if plugin ID conflicts or capabilities missing. */ register(plugin: PipelinePlugin): Result; /** Resolve a plugin by ID. Returns undefined if not registered or disabled. */ resolve(pluginId: string): PipelinePlugin | undefined; /** List all enabled plugins with their manifests. */ listEnabled(): readonly PluginManifest[]; /** Check if a plugin is registered and enabled. */ isEnabled(pluginId: string): boolean; /** Freeze the registry — no further registrations allowed. */ freeze(): void; /** Whether the registry is frozen. */ readonly frozen: boolean; } /** Decision returned by a policy rule evaluation. */ type PolicyDecision = { readonly allow: true; } | { readonly allow: false; readonly reason: string; readonly escalateTo?: string; }; /** * Typed snapshot of the pipeline state available to policy rules (#2932). * * Listing the fields by name (instead of an untyped `Record`) * surfaces missing-producer bugs at compile time. The pre-#2932 untyped * shape let `securityReviewRule`, `costBudgetRule`, `highRiskApprovalRule`, * and `boundedIterationRule` read keys that no producer ever wrote — every * comparison evaluated against `undefined`, so every rule allowed. Those * four rules were deleted in the same change; this interface lists only * the fields with a real producer chain. * * Adding a new rule means adding its input field here AND wiring a * producer that writes it onto `TaskContract.metadata` upstream of * `checkPipelinePolicy`. */ interface PipelineStateSnapshot { /** * Caller trust tier (`'1'`..`'4'` per `security/trust-types.ts`). Producers * include `trust-classifier`, `input-sanitizer`, `firewall-pipeline`, and * `mcp/middleware/request-context`; threading the value into * `TaskContract.metadata.trustTier` is owner-scoped follow-up work — see * the corresponding issue. * * ABSENT MEANS UNTRUSTED, NOT ALLOWED (#4821). An absent or non-numeric * value is coerced to `4` and DENIES — see `trustTierRule` below. This doc * previously claimed the opposite ("fail-open default for unknown trust"), * describing a pre-hardening behaviour the code no longer has. * * That is the correct default and should stay: fail-closed on unknown * provenance is what `.rules/untrusted-input.md` requires. Do not "fix" the * rule to match the old comment. The practical consequence, worth knowing * before planning enforcement work, is that an UNWIRED producer is the DENY * case rather than the safe one. */ readonly trustTier?: string; } /** Context provided to policy rules for evaluation. */ interface PolicyContext { readonly taskId: string; readonly stageId: string; readonly stageType: string; readonly pipelineState: PipelineStateSnapshot; } /** A policy rule with priority-ordered evaluation. */ interface PolicyRule { readonly id: string; readonly priority: number; evaluate(context: PolicyContext): PolicyDecision; } /** Policy engine interface. */ interface IPolicyEngine { evaluate(gate: PolicyGateSpec, context: PolicyContext): PolicyDecision; registerRule(rule: PolicyRule): void; listRules(): readonly PolicyRule[]; } /** * In-memory policy engine with priority-ordered rule evaluation. * * Rules are evaluated in descending priority order. * First blocking rule short-circuits evaluation. */ declare class PolicyEngine implements IPolicyEngine { private readonly rules; registerRule(rule: PolicyRule): void; evaluate(gate: PolicyGateSpec, context: PolicyContext): PolicyDecision; listRules(): readonly PolicyRule[]; private getRulesForGate; } /** All built-in policy rules. */ declare const BUILT_IN_RULES: readonly PolicyRule[]; /** * Creates a PolicyEngine with all built-in rules registered. */ declare function createDefaultPolicyEngine(): PolicyEngine; /** Policy enforcement mode. */ type PolicyMode = 'off' | 'warn' | 'block'; /** Options for PolicyEvaluator. */ interface PolicyEvaluatorOptions { /** Only `listRules()` is consumed, so the interface — not the class — suffices. */ readonly engine: IPolicyEngine; readonly eventBus?: IEventBus; readonly mode?: PolicyMode; /** * Optional DURABLE audit trail (#3710). When present, each violation is ALSO * appended to the hash-chained store (dual-emit) carrying mode/ruleIds/ * stageType — so soak(warn)-vs-enforce(block) evidence survives process exit * for the tune/readiness loop. The in-memory `eventBus` emit is unchanged * (back-compat). When absent, behavior is byte-identical to before. */ readonly auditTrail?: AuditTrail; } /** Result of a policy evaluation at a stage boundary. */ interface PolicyEvalResult { readonly allowed: boolean; readonly violations: readonly PolicyViolation[]; readonly mode: PolicyMode; } /** A single policy violation. */ interface PolicyViolation { readonly ruleId: string; readonly reason: string; readonly escalateTo?: string; } /** * Policy-enforcement bundle threaded to a compiled gate node (#3177). * * When attached to `PlanCompileOptions`, each policy gate node evaluates * `evaluatePipelinePolicy` at runtime instead of being a no-op pass. When * absent, gates stay no-op passes (back-compat). */ interface GatePolicyEnforcement { /** Engine whose rules are evaluated at the gate boundary. */ readonly engine: IPolicyEngine; /** * Snapshot of pipeline state available to policy rules (carries `trustTier`). * Captured at compile time from the TaskContract metadata by the caller. */ readonly pipelineState: PipelineStateSnapshot; /** Optional event bus; policy.evaluated events are emitted on violations. */ readonly eventBus?: IEventBus; /** * Optional DURABLE audit trail (#3710) — forwarded to * {@link evaluatePipelinePolicy} so gate decisions are persisted to the * hash-chained store in addition to the in-memory bus. */ readonly auditTrail?: AuditTrail; /** * Effective enforcement mode for gate nodes. WARN by default (#3177 * condition 1): a gate with no explicit mode does NOT halt, so a stage * lacking trust metadata is not blocked out of the box. Block is opt-in. */ readonly mode?: PolicyMode; } /** * Reads policy mode from V2 config (umbrella + individual override). * Default: `block` in full mode, `warn` in partial, `off` when V2 is off. */ declare function getPolicyMode(): PolicyMode; /** * Evaluates all registered policy rules for a stage boundary. * * In WARN mode, violations are logged and emitted but execution continues. * In BLOCK mode, violations halt the pipeline. * In OFF mode, evaluation is skipped entirely. */ declare function evaluatePipelinePolicy(options: PolicyEvaluatorOptions, context: PolicyContext): PolicyEvalResult; /** Result of plan compilation. */ type CompileResult$1 = { readonly ok: true; readonly value: CompiledGraph; } | { readonly ok: false; readonly error: string; }; /** Options for plan compilation. */ interface PlanCompileOptions { /** Plugin registry for resolving stage handlers. When provided, stages with * a registered pluginId will use the plugin's execute() method. */ readonly pluginRegistry?: IPluginRegistry; /** * Policy enforcement for gate nodes (#3177). When provided, each policy gate * node evaluates `evaluatePipelinePolicy` at runtime — denying (in BLOCK * mode) by throwing `PolicyBlockedError`, which halts the pipeline. When * absent, gate nodes remain no-op passes (back-compat). */ readonly policyEnforcement?: GatePolicyEnforcement; } /** * Compiles a PlanContract into a CompiledGraph. * * - Each stage becomes a node with a handler (plugin-backed or placeholder) * - Dependencies become fixed edges * - Policy gates become gate nodes between stages * - Stages with no dependencies get edges from START * - Stages with no dependents get edges to END */ declare function compilePlan(plan: PlanContract, options?: PlanCompileOptions): CompileResult$1; /** * Injectable pipeline dependencies. Every field is optional; an unset field * falls back to its documented process-global default at resolve time. */ interface PipelineDeps { /** * Plugin registry for resolving stage handlers. Defaults to the global * pipeline registry (`getPipelinePluginRegistry()`) when unset. */ readonly pluginRegistry?: IPluginRegistry; } /** Fully-resolved pipeline dependencies — every field concrete. */ interface ResolvedPipelineDeps { readonly pluginRegistry: IPluginRegistry; } /** * Resolves a {@link PipelineDeps} bundle, filling any unset field from its * documented global default. An injected field is returned untouched; an omitted * field returns the process-global default. The only side effect is the lazy, * idempotent creation of the global registry inside `getPipelinePluginRegistry()`. */ declare function resolvePipelineDeps(deps?: PipelineDeps): ResolvedPipelineDeps; /** Compiled pipeline ready for execution. */ interface CompiledPipeline { readonly graph: CompiledGraph; readonly plan: PlanContract; } /** Pipeline execution result. */ interface PipelineResult { readonly success: boolean; readonly stepsExecuted: number; readonly durationMs: number; readonly error?: string; /** Per-step breakdown when continueOnFailure is enabled. */ readonly stepResults?: readonly StepOutcome[] | undefined; /** * Raw per-node results from the run (#3534). Retained so `retryFailed` can * replay prior successes and re-run only the failed nodes; carries the * `isRetryable` signal used to gate the retry. */ readonly nodeResults?: readonly NodeResult[] | undefined; } /** Outcome of a single pipeline step. */ interface StepOutcome { readonly stepId: string; readonly status: 'succeeded' | 'failed' | 'skipped'; readonly durationMs: number; readonly error?: string | undefined; } /** Pipeline execution options. */ interface PipelineExecuteOptions { readonly signal?: AbortSignal; readonly maxSteps?: number; readonly timeout?: number; readonly onStageComplete?: (stageId: string) => void; /** When true, continue executing independent steps after a failure. */ readonly continueOnFailure?: boolean; /** * Prior NodeResults to replay (#3534) — succeeded nodes are reused instead of * re-executed. Set by `retryFailed` so a retry re-runs only the failed nodes. */ readonly priorResults?: ReadonlyMap; /** EventBus for trace persistence. When provided, creates a TraceWriter. */ readonly eventBus?: IEventBus; /** * Override base directory for trace output. Default: `getDefaultRunsDir()`, * i.e. `nexusDataPath('runs')` — per-repo aware. NOT `getNexusDataDir()/runs`, * which bypassed per-repo routing (#2889). */ readonly runsDir?: string; } /** Compile result type. */ type CompileResult = { readonly ok: true; readonly value: CompiledPipeline; } | { readonly ok: false; readonly error: string; }; /** Execute result type. */ type ExecuteResult = { readonly ok: true; readonly value: PipelineResult; } | { readonly ok: false; readonly error: string; }; /** * Compiles PlanContracts and executes them as graphs. */ declare class PipelineRunner { /** Compiles a PlanContract into a CompiledPipeline. */ compile(plan: PlanContract, options?: PlanCompileOptions): CompileResult; /** Executes a compiled pipeline. */ execute(pipeline: CompiledPipeline, task: TaskContract, options?: PipelineExecuteOptions): Promise; /** * Retries a previous run's failures **selectively** (#3534): prior successful * nodes are replayed (not re-executed) via `priorResults`, so only the failed * nodes and their dependents run again. * * Gated on retryability: retries only when at least one *failed* node is * `isRetryable` (transient). If every failure is permanent * (validation/permission/business/internal) it returns `previousResult` * unchanged rather than looping on errors that won't clear. * * Back-compat: a `previousResult` without `nodeResults` (e.g. an older caller) * falls back to the prior whole-pipeline retry gated on `stepResults`. * * NOTE: non-retryable failures that coexist with a retryable one still re-run * (and re-fail) under `continueOnFailure`; pinning them as terminal is a * future refinement. */ retryFailed(pipeline: CompiledPipeline, previousResult: PipelineResult, task: TaskContract, options?: PipelineExecuteOptions): Promise; /** Pre-#3534 whole-pipeline retry, kept for results lacking `nodeResults`. */ private retryFailedLegacy; } /** * Options for controlling plugin registry behavior. * * Both fields are deprecated (#5097). No production construction sets them: * `registerCorePlugins` / `createCorePluginRegistry` build the registry with * no options, every `CORE_PLUGINS` manifest is `experimental: false`, and the * registry is frozen right after core registration — so only core plugins * ever load and the experimental gate cannot open. The fields stay accepted * (and still deny) because they are public API; removal is tracked in #5097 * for the next major. */ interface PluginRegistryOptions { /** * Allow experimental plugins to be registered. * * @deprecated No production construction sets this; only core plugins load. * Still accepted and still gates as before. Removal tracked in #5097 (next major). */ readonly experimentalEnabled?: boolean; /** * Explicit allowlist of experimental plugin IDs. * * @deprecated No production construction sets this; only core plugins load. * Still accepted and still gates as before. Removal tracked in #5097 (next major). */ readonly experimentalAllow?: readonly string[]; } /** * In-memory plugin registry with experimental gating. * * Plugins are registered during startup. After freeze(), * no further registrations are accepted. */ declare class PluginRegistry implements IPluginRegistry { private readonly plugins; private readonly options; private isFrozen; constructor(options?: PluginRegistryOptions); get frozen(): boolean; register(plugin: PipelinePlugin): Result; resolve(pluginId: string): PipelinePlugin | undefined; listEnabled(): readonly PluginManifest[]; isEnabled(pluginId: string): boolean; freeze(): void; private checkDuplicate; private validateManifest; private checkExperimentalGate; } /** Options for EventBus behavior. */ interface EventBusOptions { readonly maxBufferSize?: number; } /** * In-memory event bus with bounded circular buffer. * * Events are stored in a circular buffer. When the buffer is full, * the oldest events are evicted. Subscribers receive events that * match their filter. Handler errors are caught and logged. */ declare class EventBus implements IEventBus { private readonly buffer; private readonly subs; private emitCount; constructor(options?: EventBusOptions); get totalEmitted(): number; get bufferSize(): number; /** Number of active subscriptions (for observability/testing). */ get subscriptionCount(): number; emit(event: PipelineEvent): void; subscribe(filter: EventFilter, handler: EventHandler): Unsubscribe; query(filter: EventFilter, limit?: number): readonly PipelineEvent[]; private addToBuffer; private notifySubscribers; } /** * ArtifactStore — V2 Pipeline Artifact Storage (Issue #912, Phase 4-3) * * In-memory artifact store with bounded capacity and FIFO eviction. * Tracks provenance chains for artifact traceability. * * @see docs/v2/08-observability-eventing.md * @module pipeline/artifact-store */ /** Full artifact with content and metadata. */ interface Artifact { readonly id: string; readonly type: ArtifactType; readonly content: unknown; readonly metadata: Record; readonly createdBy: string; readonly createdAt: number; readonly inputRefs: readonly ArtifactRef[]; } /** Filter for querying artifacts. */ interface ArtifactFilter { readonly type?: ArtifactType; readonly createdBy?: string; } /** Provenance entry for artifact traceability. */ interface ProvenanceEntry { readonly artifactId: string; readonly plugin: string; readonly timestamp: number; readonly inputArtifacts: readonly string[]; } /** Artifact store interface. */ interface IArtifactStore { put(artifact: Artifact): ArtifactRef; get(ref: ArtifactRef): Artifact | undefined; query(filter: ArtifactFilter): readonly ArtifactRef[]; provenance(ref: ArtifactRef): readonly ProvenanceEntry[]; readonly size: number; } /** Options for ArtifactStore behavior. */ interface ArtifactStoreOptions { readonly maxArtifacts?: number; readonly maxContentSize?: number; } /** * In-memory artifact store with bounded capacity. * * When the store exceeds maxArtifacts, the oldest artifacts are evicted * (FIFO — insertion order, never reordered on `get()`). Content size is * validated on put(). * * This is a bounded in-memory working cache, NOT the durable audit * substrate (#2867): once `maxArtifacts` is reached, old artifacts and * their provenance are dropped. For tamper-evident, retained audit * history use the on-disk Merkle audit log via the `verify_audit_chain` * MCP tool. */ declare class ArtifactStore implements IArtifactStore { private readonly artifacts; private readonly insertOrder; private readonly maxArtifacts; private readonly maxContentSize; constructor(options?: ArtifactStoreOptions); get size(): number; put(artifact: Artifact): ArtifactRef; get(ref: ArtifactRef): Artifact | undefined; query(filter: ArtifactFilter): readonly ArtifactRef[]; /** * Returns the full provenance chain for an artifact — the artifact * itself plus every ancestor transitively reachable via `inputRefs` * (#2867). Iterative DFS; the `visited` set makes it safe against * cycles and diamond/multi-parent DAGs (each artifact appears once). * * Entries are in reachability (start-node-first DFS) order, not * topological order. An ancestor that has been FIFO-evicted from the * store is silently skipped — the chain truncates there rather than * throwing. A missing root returns `[]`. */ provenance(ref: ArtifactRef): readonly ProvenanceEntry[]; private validateContentSize; private evictIfNeeded; } /** Returns the global ArtifactStore (created lazily on first call). */ declare function getPipelineArtifactStore(): IArtifactStore; /** Resets the global ArtifactStore (for testing). */ declare function resetPipelineArtifactStore(): void; /** * Creates a subscriber that bridges EventBus events to OutcomeStore. * * Listens for `stage.failed` events and records them as failed TaskOutcome * entries in the OutcomeStore. * * Returns an Unsubscribe handle; the caller owns the lifecycle. * * There is deliberately no server-wide singleton. #2938 added a * `startFeedbackSubscriber` / `shutdownFeedbackSubscriber` pair, and #5003's * panel then removed this bridge from the server: `StageFailedEvent` carries no * `cli`, so the subscriber hardcoded `cli: 'claude'` on every stage failure and * double-counted against `agent-executor`, which is now the single canonical * outcome writer. The `start` half was dropped from `initV2PipelineSubsystems` * and the pair was left behind — `shutdown` still called from `cli-server.ts` * as an unconditional no-op, and the init log still reporting * `feedbackSubscriber: 'active'`. Both are gone; this function stays because it * is public API for SDK embedders who DO manage their own store. * * @returns Unsubscribe function to stop the bridge. */ declare function createFeedbackSubscriber(bus: IEventBus, store: OutcomeStore): Unsubscribe; /** Result of creating a delegate pipeline. */ type DelegatePipelineResult = { readonly ok: true; readonly value: CompiledPipeline; } | { readonly ok: false; readonly error: string; }; /** * Creates a compiled V2 pipeline for delegate_to_model from a TaskContract. * * The pipeline has a single 'route' stage and no policy gate (#4657), so the * compile call passes no `policyEnforcement` bundle: with zero gates there is * no node that would consult one, and supplying it read as "policy enforced * at the stage boundary" when nothing was. Routing logic lives in the stage * handler (placeholder here, real handler injected by the MCP tool). */ declare function createDelegatePipeline(task: TaskContract): DelegatePipelineResult; /** Minimal input shape matching DelegateInput. Avoids circular mcp/tools import. */ interface DelegateInputLike { readonly task: string; readonly preferred_capability?: string | undefined; readonly model_hint?: string | undefined; readonly billing_mode?: string | undefined; } /** Metrics from V2 pipeline execution. */ interface PipelineMetrics { readonly compiled: boolean; readonly executed: boolean; readonly stepsExecuted: number; readonly durationMs: number; /** True only when policy actually stopped the run (block mode + denial). */ readonly policyBlocked?: boolean; /** * Violations the policy evaluator found, present whether or not they * stopped the run. * * Under `warn` mode `PolicyEvalResult.allowed` is `true` regardless of * violations, so a metrics object that only populated this alongside * `policyBlocked` reported a warn-mode denial identically to a clean * evaluation (#5862). Read `policyBlocked` for "did it stop", this for * "what did it find". */ readonly policyViolations?: readonly string[]; /** The mode those violations were evaluated under, when there are any. */ readonly policyMode?: PolicyMode; } /** Optional contract-construction options (#2957). */ interface DelegateContractOpts { /** Caller trust tier from RequestContext (`'1'..'4'`). */ readonly trustTier?: string; } /** * Converts delegate_to_model input into a V2 TaskContract. * Input fields are preserved in metadata for downstream pipeline stages. */ declare function delegateInputToTaskContract(input: DelegateInputLike, opts?: DelegateContractOpts): TaskContract; /** * Compiles and executes a V2 pipeline for the given TaskContract. * Returns metrics for observability — never throws. * * This path performs no route-stage policy evaluation (#5485): the only * built-in rule denies execute stages, so such a check could not fail. The * enforcing seams remain the execute check in `v2-orchestrate.ts` and * `enforceConsensusExecutePolicy` in `dev-pipeline.ts`. */ declare function executeDelegatePipeline(task: TaskContract): Promise; /** * Evaluates pipeline policy before execution. * Builds PolicyContext from TaskContract metadata and stage type. * Uses the default PolicyEngine, whose `BUILT_IN_RULES` is the single * `trustTierRule`. The four siblings that once sat beside it were removed as * unwired (`policy-engine.ts`), so no cost, security or high-risk gate runs * on this path. */ declare function checkPipelinePolicy(task: TaskContract, stageType: string): PolicyEvalResult; /** All core plugins in registration order. */ declare const CORE_PLUGINS: readonly PipelinePlugin[]; /** Result of core plugin registration. */ interface CorePluginRegistrationResult { readonly registered: number; readonly failed: number; readonly errors: readonly string[]; } /** * Registers all core plugins into a PluginRegistry and freezes it. * Returns registration summary. Never throws. */ declare function registerCorePlugins(registry?: PluginRegistry): CorePluginRegistrationResult; /** * Creates a PluginRegistry with core plugins pre-registered and frozen. * Convenience function for server startup. */ declare function createCorePluginRegistry(): PluginRegistry; /** Returns the global PluginRegistry (created lazily on first call). */ declare function getPipelinePluginRegistry(): PluginRegistry; /** Resets the global PluginRegistry (for testing). */ declare function resetPipelinePluginRegistry(): void; /** Options for the EventBus bridge. */ interface EventBusBridgeOptions { /** V2 pipeline EventBus to subscribe to. */ readonly source: IEventBus; /** Optional topic prefix for forwarded events. Defaults to 'pipeline'. */ readonly topicPrefix?: string; } /** Result of bridge initialization. */ interface PipelineBridgeResult { /** Number of events forwarded so far. */ readonly forwarded: () => number; /** Unsubscribe from the V2 bus (cleanup). */ readonly dispose: Unsubscribe; } /** * Creates a bridge that forwards V2 pipeline events to the V1 agent EventBus. * * Each V2 event is converted to a V1 DomainEvent with: * - topic: `{prefix}.{v2EventType}` (e.g. `pipeline.task.created`) * - payload: all V2 event fields except type/timestamp * - correlationId: executionId or taskId from V2 event * * The bridge is fire-and-forget: forwarding errors are logged, not thrown. */ declare function createEventBusBridge(options: EventBusBridgeOptions): PipelineBridgeResult; /** Minimal shape of orchestrate input (avoids circular import). */ interface OrchestrateInputLike { readonly task: string; readonly context?: Record; readonly maxIterations?: number; } /** Optional contract-construction options (#2957). */ interface OrchestrateContractOpts { /** Caller trust tier from RequestContext (`'1'..'4'`). */ readonly trustTier?: string; } /** Converts orchestrate input to a TaskContract. */ declare function orchestrateInputToTaskContract(input: OrchestrateInputLike, opts?: OrchestrateContractOpts): TaskContract; /** Executes the V2 orchestrate pipeline and returns metrics. */ declare function executeOrchestratePipeline(task: TaskContract): Promise; /** * V2 Pipeline Configuration — Umbrella mode flags (Issue #925, Phase F) * * Centralizes all V2 pipeline feature flags into a single config module. * Individual flags (`NEXUS_V2_DELEGATE`, `NEXUS_V2_ORCHESTRATE`, `NEXUS_V2_POLICY_MODE`) * can override the umbrella `NEXUS_V2_MODE` flag. * * @module pipeline/v2-config */ /** V2 umbrella mode. */ type V2Mode = 'off' | 'partial' | 'full'; /** Resolved V2 configuration. */ interface V2Config { /** Overall V2 mode. */ readonly mode: V2Mode; /** Whether delegate_to_model uses V2 pipeline. */ readonly delegateEnabled: boolean; /** Whether orchestrate uses V2 pipeline. */ readonly orchestrateEnabled: boolean; /** Policy enforcement mode. */ readonly policyMode: 'off' | 'warn' | 'block'; /** Whether AOrchestra dynamic agent planning is enabled (Issue #935). */ readonly aorchestraEnabled: boolean; /** Whether AOrchestra worker dispatch is enabled (Issue #1321). */ readonly dispatchEnabled: boolean; } /** * Resolves the full V2 configuration from environment variables. * * Priority: individual flag > umbrella flag > defaults. * * | NEXUS_V2_MODE | delegate | orchestrate | policy | * |---------------|----------|-------------|--------| * | full (default)| true | true | block | * | partial | true | false | warn | * | off | false | false | off | */ declare function resolveV2Config(): V2Config; /** * Expert Bridge — Programmatic access to the execute_expert pipeline (#1693) * * Provides a clean wrapper for calling experts with the full pipeline: * timeout, fallback cascade, degradation detection, heartbeat, outcome recording. * * DRY: reuses createBuiltInExpert + CompositeRouter instead of reimplementing. * * @module pipeline/expert-bridge */ /** Result of an expert execution. */ interface ExpertBridgeResult { readonly success: boolean; readonly text: string; readonly expertType: BuiltInExpertType; readonly durationMs: number; readonly error?: string; /** * CLI that actually executed the task, resolved from the underlying * `CliResponse.model` via `getCliForModelId`. Undefined when the bridge * failed before dispatch (no adapters / circuit-open / rate-limit cap). * Callers writing to OutcomeStore should use this rather than hardcoding * a cli — see #2823 (#1154 regression). */ readonly cli?: CliNameLiteral; /** * Total tokens (input + output) the underlying CLI/adapter reported for this * call, when available (#3396). Best-effort: `CliResponse.usage` is optional * — CLI-subprocess paths whose `extractUsage` returns null leave this * undefined. Consumers (budget enforcement #3395, model.called attribution * #3387, routing-experience metrics) must tolerate `undefined`. */ readonly tokensUsed?: number; /** * Concrete model id the underlying adapter reported (`CliResponse.model`), * when present (#3387). Distinct from {@link cli} (the slot): one CLI can run * several models. Undefined when the adapter didn't report a model or the * bridge failed before dispatch. Required to emit a `model.called` event. */ readonly model?: string; /** * Input/output token split from the adapter's `CliResponse.usage` (#3387), * when reported. Best-effort like {@link tokensUsed}; both undefined together * when no usage was available. `tokensIn + tokensOut` reconciles with * `tokensUsed` (single source of truth — both derive from the same record). */ readonly tokensIn?: number; readonly tokensOut?: number; } /** * Execute an expert task with the full nexus-agents expert pipeline. * * Creates a built-in expert, executes via CompositeRouter (for intelligent * CLI routing), and records outcomes. Falls back gracefully on failure. * * @param expertType - Built-in expert type (code, architecture, security, qa, etc.) * @param prompt - Task prompt for the expert * @returns Expert result with text output */ declare function executeExpert(expertType: BuiltInExpertType, prompt: string): Promise; declare function executeExpert(expertType: BuiltInExpertType, prompt: string, options: { workDir?: string | undefined; }): Promise; /** Opt-in per-run budget configuration (absent → enforcement off). */ interface AgentBudgetConfig { /** Hard token ceiling for the whole run. */ readonly maxTokens: number; /** Fraction of `maxTokens` at which the circuit opens (default 0.95). */ readonly criticalThreshold?: number; } /** * Agent Executor core — the helpers every pipeline stage shares (#1684, #6331). * * Stage-event emission, OutcomeStore recording, the budget-guarded expert * call, progress comments and the executor config. Extracted from * `agent-executor.ts` so each stage module imports one seam instead of the * whole executor. * * @module pipeline/agent-executor-core */ /** Configuration for the agent executor. */ interface AgentExecutorConfig { readonly scanTarget?: string | undefined; readonly simulateVotes?: boolean | undefined; /** Voting strategy for consensus stages (default: higher_order). */ readonly votingStrategy?: 'simple_majority' | 'supermajority' | 'unanimous' | 'higher_order' | 'proof_of_learning' | 'opinion_wise' | undefined; /** Use 3 agents instead of the full 7-role panel for faster voting (default: false). */ readonly quickMode?: boolean | undefined; readonly tracker?: ITaskTracker | undefined; readonly issueNumber?: number | undefined; readonly repo?: string | undefined; /** * Opt-in per-run token budget (#3395). When set, expert calls are metered * through a {@link BudgetGuard}: once cumulative usage crosses the ceiling, * further expert calls short-circuit to a failure result (stopping spend) * rather than aborting mid-pipeline. Absent → no enforcement (default). */ readonly budget?: AgentBudgetConfig | undefined; /** * Caller authentication from measuredTrustTier(), recorded at stage entry. * Absent callerInfo means 'unmeasured'; no callerInfo producer exists today. * Record-only: no stage refuses on this value. Takes precedence over trustTier. */ readonly callerTrustTier?: string | undefined; /** * Caller authentication, emitted with the same value as callerTrustTier. * @deprecated Use callerTrustTier. Removal is scheduled for the next major. */ readonly trustTier?: string | undefined; /** Whether the handler's sanitizer changed its input; absent means 'unmeasured'. */ readonly inputSanitization?: 'unmeasured' | 'unmodified' | 'modified' | undefined; /** Sanitizer counts, emitted beside inputSanitization only when it is 'modified'. */ readonly inputSanitizationCounts?: { readonly tagsRemoved: number; readonly commentsRemoved: number; readonly fieldsModified: number; } | undefined; } /** Flush pipeline memory session. */ declare function flushPipelineMemory(): void; /** * Agent Executor — Connects pipeline stages to nexus-agents infrastructure (#1684) * * DRY integration (Issue #1691): * - CompositeRouter for intelligent multi-CLI routing (#1692) * - Pipeline observability events + OutcomeStore recording (#1696) * - Task tracker for GitHub/GitLab/JSON issue management * * @module pipeline/agent-executor */ declare function createAgentStages(config?: AgentExecutorConfig): DevPipelineStages; /** * Research Trigger — Auto-create pipeline tasks from research discoveries (#1715) * * When research_discover finds high-quality papers/repos, this module * converts them into PipelineTask[] for the dev pipeline to assess. * Part of the Central Workflow Hub (#1711). * * @module pipeline/research-trigger */ /** Configuration for research trigger behavior. */ interface ResearchTriggerConfig { /** Minimum quality score to trigger (0-10). Default: 7 */ readonly qualityThreshold?: number | undefined; /** Max tasks per invocation. Default: 3 */ readonly maxTriggers?: number | undefined; /** Topic filter for research_discover. */ readonly topic?: string | undefined; /** Known task IDs to skip (dedup). */ readonly existingTaskIds?: ReadonlySet | undefined; } /** * Check for research discoveries and convert high-quality ones to pipeline tasks. * * Calls research_discover via expert-bridge, filters by quality threshold, * deduplicates against known tasks, and rate-limits output. * * Returns empty array when expert-bridge is unavailable (graceful degradation). */ declare function checkForResearchTriggers(config?: ResearchTriggerConfig): Promise; /** * Pipeline Checkpoint — Persist stage results for crash recovery (#1703) * * DRY: reuses ensureCheckpointDir from wave-checkpoint-persistence for * directory management and path security. Pipeline-specific JSONL schema. * * Storage: /.nexus-agents/checkpoints/pipeline-{sessionId}.jsonl * (checkpoints/ is per-repo state — epic #2872) * * @module pipeline/pipeline-checkpoint */ /** Stages that can be checkpointed. */ type PipelineStage = 'research' | 'plan' | 'vote' | 'decompose' | 'implement' | 'security'; /** Discriminated union of stage data. */ type PipelineStageData = { readonly type: 'research'; readonly text: string; } | { readonly type: 'plan'; readonly text: string; readonly iterations: number; } | { readonly type: 'vote'; readonly approved: boolean; readonly conditional: boolean; readonly conditions?: readonly string[]; readonly caveats?: readonly string[]; readonly iterations: number; } | { readonly type: 'decompose'; readonly tasks: readonly PipelineTask[]; } | { readonly type: 'implement'; readonly tasks: readonly PipelineTask[]; } | { readonly type: 'security'; readonly passed: boolean; }; /** Partial pipeline state loaded from checkpoints. */ interface PipelineCheckpointState { readonly research?: string; readonly plan?: string; readonly voteIterations?: number; readonly voteConditional?: boolean; readonly voteConditions?: readonly string[]; readonly voteCaveats?: readonly string[]; readonly tasks?: readonly PipelineTask[]; readonly implementedTasks?: readonly PipelineTask[]; readonly securityPassed?: boolean; readonly lastCompletedStage?: PipelineStage; } /** Append a stage checkpoint to disk. */ declare function saveStageCheckpoint(sessionId: string, stage: PipelineStage, data: PipelineStageData, customDir?: string): boolean; /** Load checkpoint state for a session. Returns null if no checkpoints exist. */ declare function loadCheckpointState(sessionId: string, customDir?: string): PipelineCheckpointState | null; /** Delete checkpoint file on successful completion. */ declare function cleanupCheckpoint(sessionId: string, customDir?: string): boolean; /** Build a DevPipelineResult from checkpoint state (for resume scenarios). */ declare function checkpointToResult(state: PipelineCheckpointState): Partial; /** * Pipeline Observability — Shared stage event emission (#1734, Phase 1.1) * * Extracts the duplicated emitStageEvent pattern from agent-executor.ts * and pipeline-runner.ts into a single shared helper. * * @module pipeline/pipeline-observability */ /** Options for emitting a stage started event. */ interface StageStartedOptions { readonly bus?: IEventBus | undefined; readonly executionId: string; readonly stageId: string; readonly pluginId?: string | undefined; } /** Options for emitting a stage completed event. */ interface StageCompletedOptions { readonly bus?: IEventBus | undefined; readonly executionId: string; readonly stageId: string; readonly durationMs: number; readonly success?: boolean | undefined; } /** Options for emitting a stage failed event. */ interface StageFailedOptions { readonly bus?: IEventBus | undefined; readonly executionId: string; readonly stageId: string; readonly error: string; /** * Concrete model id the failing stage's executor reported, when known * (#4194). Omit for stages with no single model — never guess. */ readonly model?: string | undefined; } /** Emit a stage.started event. */ declare function emitStageStarted(options: StageStartedOptions): void; /** Emit a stage.completed event. */ declare function emitStageCompleted(options: StageCompletedOptions): void; /** Emit a stage.failed event. */ declare function emitStageFailed(options: StageFailedOptions): void; /** * Convenience wrapper matching agent-executor's original signature. * Emits stage events using the global event bus with a prefixed executionId. */ declare function emitPipelineStageEvent(prefix: string, stage: string, status: 'started' | 'completed' | 'failed', details?: Record): void; /** * Iterative Consensus Stage — Reusable vote loop (#1734, Phase 1.2) * * Extracts the plan→vote→feedback iteration pattern from agent-executor.ts * into a reusable stage. Wraps executeVoting from consensus-vote.ts. * * @module pipeline/iterative-consensus */ /** Configuration for an iterative consensus vote. */ interface IterativeConsensusConfig { /** Maximum plan→vote iterations (default: 3). */ readonly maxIterations?: number | undefined; /** Use simulated votes (for testing). */ readonly simulateVotes?: boolean | undefined; /** Use quick mode (3 agents instead of the full 7-role panel). */ readonly quickMode?: boolean | undefined; /** Voting strategy (default: 'higher_order'). */ readonly strategy?: VotingStrategy | undefined; /** * #4138: error policy for votes run by this reusable helper (default: * 'absolute_quorum'). An errored voter degrades to a recoverable `no_quorum` * handled by `maxNoQuorumRetries`. Overridable per caller. * * The production dev-pipeline plan gate applies the same policy directly through * `DevPipelineStages.vote`; it does not call `runIterativeConsensus`. */ readonly errorPolicy?: ErrorPolicy | undefined; /** * #4135: how many times to re-run the SAME plan when a vote returns * `no_quorum` — a missing/errored voice, not a rejection — before giving up * (default: 2). Counted SEPARATELY from `maxIterations`: a quorum void is a * recoverable "re-run the missing voice" state, not a plan-revision trigger, so * it must not consume the refine budget. */ readonly maxNoQuorumRetries?: number | undefined; /** Max proposal length sent to voters (default: 4000). */ readonly maxProposalLength?: number | undefined; /** Logger instance. */ readonly logger?: ILogger | undefined; /** Pipeline prefix for observability events. */ readonly pipelinePrefix?: string | undefined; } /** Result of the iterative consensus process. */ interface IterativeConsensusResult { readonly vote: VoteResult; readonly iterations: number; readonly durationMs: number; } declare function runIterativeConsensus(initialPlan: string, revisePlan: (plan: string, feedback: string) => Promise, config?: IterativeConsensusConfig): Promise; /** * Pipeline Templates — Declarative pipeline configurations (#1735, Phase 2) * * Predefined pipeline shapes that can be compiled into executable graphs. * Each template defines stage ordering and edge routing. * * @module pipeline/templates */ /** Development pipeline: research → plan → vote → decompose → implement → qa → security. */ declare const DEV_PIPELINE_TEMPLATE: PipelineTemplate; /** Security audit pipeline: analyze → scan → report. */ declare const AUDIT_PIPELINE_TEMPLATE: PipelineTemplate; /** * General-purpose pipeline for tasks that don't match a specific template. * Includes security gate (fail-safe: unclassified tasks must not bypass security). */ declare const GENERAL_PIPELINE_TEMPLATE: PipelineTemplate; /** All available pipeline templates. */ declare const PIPELINE_TEMPLATES: ReadonlyMap; /** Get a pipeline template by ID. */ declare function getTemplate(id: string): PipelineTemplate | undefined; /** List all available template IDs. */ declare function listTemplateIds(): readonly string[]; /** * Stage Wrappers — Adapt DevPipelineStages to IPipelineStage (#1735, Phase 2) * * Wraps existing agent-executor stage functions as IPipelineStage objects * that can be compiled into graph nodes. This is an adapter layer that * preserves existing behavior while enabling graph-based execution. * * @module pipeline/stage-wrappers */ /** Create a complete stage registry for the dev pipeline template. */ declare function createDevStageRegistry(stages: DevPipelineStages): Map; /** * nexus-agents/scm - Centralized Token Resolver * * Single source of truth for SCM token resolution. Priority: * 1. Explicit config (token passed directly) * 2. Environment variables (GITHUB_TOKEN, GH_TOKEN, GITLAB_TOKEN) * 3. CLI auth (gh auth token, glab auth token) * * @module scm/token-resolver * (Source: Issue #1136 — Centralized SCM Provider Module) */ /** * Resolves an SCM token using the priority chain: * 1. Explicit config * 2. Environment variables * 3. CLI auth * * @param config - Token resolution configuration * @returns Resolved token or error */ declare function resolveToken(config?: TokenResolverConfig): Promise>; /** * Synchronous check: is any token available for the given platform? * Only checks environment variables (no CLI auth, which is async). */ declare function hasToken(platform?: ScmPlatform): boolean; /** * Returns the list of environment variable names for a platform. * Useful for documentation and error messages. */ declare function getTokenEnvVars(platform?: ScmPlatform): readonly string[]; /** * nexus-agents/scm - GitHub Provider * * Unified GitHub provider using gh CLI. Implements IScmProvider with * Result-based error handling. Replaced the prior dual-path GitHub * clients (dogfooding/github-client.ts deleted in #2553; * workflows/self-development/github-client.ts deleted in #2402). * * @module scm/github-provider * (Source: Issue #1136 — Centralized SCM Provider Module) */ /** * GitHub provider using the gh CLI. * * Requires: gh CLI installed and authenticated. */ declare class GitHubProvider implements IScmProvider { readonly repo: string; readonly platform: "github"; constructor(repo: string); getIssue(number: number): Promise>; listIssues(filters?: IssueFilters): Promise>; listRepositoryLabels(): Promise>; addLabels(issueNumber: number, labels: readonly string[]): Promise>; createPR(options: CreatePROptions): Promise>; mergePR(prNumber: number, options?: MergePROptions): Promise>; getPRStatus(prNumber: number): Promise>; createIssue(title: string, body: string, labels?: readonly string[]): Promise>; addComment(issueNumber: number, body: string): Promise>; listComments(issueNumber: number): Promise>; } /** * nexus-agents/scm - GitHub Provider Trait Implementations * * Implements IScmReviewer and IScmUserInfo trait interfaces for GitHub. * Uses `gh api` for REST API access to get detailed data. * * @module scm/github-provider-traits * (Source: Issue #1136 — Centralized SCM Provider Module) */ /** * GitHub-specific reviewer that adds PR detail and review capabilities * to a GitHubProvider. Implements IScmReviewer trait. * * @example * ```typescript * const provider = createGitHubProvider('owner/repo'); * const reviewer = new GitHubReviewer(provider); * const detail = await reviewer.getPullRequestDetail(42); * ``` */ declare class GitHubReviewer implements IScmReviewer { private readonly provider; constructor(provider: GitHubProvider); getPullRequestDetail(prNumber: number): Promise>; createReview(prNumber: number, body: string, decision: ScmReviewDecision): Promise>; getIssueDetail(issueNumber: number): Promise>; listCommentDetails(issueNumber: number): Promise>; } /** * GitHub-specific user info provider. Implements IScmUserInfo trait. */ declare class GitHubUserInfo implements IScmUserInfo { fetchUserMetadata(username: string): Promise>; } /** * Creates a full-capability GitHub provider with all traits. * * Returns an object that implements IScmProvider & IScmReviewer & IScmUserInfo. * Consumers can narrow the type to only the traits they need. * * @example * ```typescript * const provider = createFullGitHubProvider('owner/repo'); * // Use as ReviewCapableProvider * const detail = await provider.getPullRequestDetail(42); * // Use as IScmUserInfo * const user = await provider.fetchUserMetadata('octocat'); * ``` */ declare function createFullGitHubProvider(repo: string): GitHubProvider & IScmReviewer & IScmUserInfo; /** * nexus-agents/scm - Provider Factory * * Creates IScmProvider instances based on platform and configuration. * Handles token resolution automatically. * * @module scm/factory * (Source: Issue #1136 — Centralized SCM Provider Module) */ /** Configuration for creating an SCM provider. */ interface CreateScmProviderConfig { /** Repository in owner/repo format */ readonly repo: string; /** SCM platform (default: github) */ readonly platform?: ScmPlatform; /** Token configuration (env vars checked automatically if omitted) */ readonly token?: TokenResolverConfig; } /** * Creates an SCM provider for the specified repository. * * Token resolution is automatic — checks env vars and CLI auth. * Currently supports GitHub (gh CLI). GitLab/Gitea planned. * * @param config - Provider configuration * @returns SCM provider instance or error * * @example * ```typescript * const result = await createScmProvider({ repo: 'owner/repo' }); * if (!result.ok) { console.error(result.error); return; } * const issues = await result.value.listIssues(); * ``` */ declare function createScmProvider(config: CreateScmProviderConfig): Promise>; /** * Creates a GitHub provider directly (convenience shortcut). * * @param repo - Repository in owner/repo format * @returns GitHub provider instance */ declare function createGitHubProvider(repo: string): IScmProvider; export { ALLOWED_COMMANDS, ARTIFACT_TYPES, AST_RULE_LANGUAGES, AST_RULE_SEVERITIES, AUDIT_PIPELINE_TEMPLATE, AbTestTracker, type ActionContext, type ActionRecord, type ActionValidation, type ActionValidationResult, type ActivationOptions, type ActivationStrategy, ActivationStrategySchema, type ActivityItem, type AdapterConfig, AdapterConfigSchema, type AdapterCreator, AdapterFactory, type AdapterLatencyConfig, type AdapterLatencyResult, AdapterModelError, RateLimiter as AdapterRateLimiter, type RateLimiterConfig as AdapterRateLimiterConfig, type RegisterOptions$1 as AdapterRegisterOptions, type AdapterScenarioResult, type AdaptiveOrchestratorOptions, type AdaptiveOrchestratorResult, type AdaptiveThresholdResult, type AgentAction, AgentActionSchema, type AgentActionType, AgentCapability, type AgentCluster, AgentError$1 as AgentError, type AgentEvent, AgentEventSchema, type AgentExecutorConfig, type AgentFinding, AgentFindingSchema, type AgentId, type AgentMessage, AgentMessageSchema, type AgentMessageType, type AgentPairKey, AgentPerformance, type AgentResponse, type AgentRole, AgentRoleSchema, type AgentRoleType, type AgentRunResult, type AgentState$2 as AgentState, AgentStateMachine, type AgentStatus, StepExecutor as AgentStepExecutor, type AgentStopReason, type AgentTurn, AgentVoteResult, AgenticAdapter, type AgenticAdapterOptions, type ToolCall as AgenticToolCall, type ToolResult as AgenticToolResult, type AggregatedResult, type AggregationMetadata, type AggregationStrategy, type AggregatorInput, type AggregatorOptions, type ApiDocumentation, type ApiEndpoint, type ApiType, type AppConfig, AppConfigSchema, type ArchitectureAnalysisResult, type ArchitectureDecision, ArchitectureExpert, type ArchitectureExpertOptions, type ArchitecturePattern, type ArchitectureStyle, type Artifact, type ArtifactFilter, type ArtifactRef, ArtifactRefSchema, ArtifactStore, type ArtifactStoreOptions, type ArtifactType, type AstQaCollectResult, type AstQaRuleFile, type AstRuleFinding, type AstRuleLanguage, type AstRuleSeverity, type AuditActor, AuditActorSchema, type AuditCategory, AuditCategorySchema, AuditError, type AuditEvent$1 as AuditEvent, type AuditEventInput, AuditEventInputSchema, AuditEventSchema, type AuditHandlerConfig, type AuditLogConfig, AuditLogConfigSchema, AuditLogger, type AuditOutcome, AuditOutcomeSchema, type AuditQueryCriteria, AuditQueryCriteriaSchema, type AuditResource, AuditResourceSchema, type AuditSeverity, AuditSeveritySchema, AuditTrail, type AuthorizationMethod, AuthorizationMethodSchema, AvailabilityCache, type AvailabilityCacheConfig, type AvailableModel, AvailableModelsCache, type AvailableModelsCacheOptions, type AvailableModelsSource, BIAS_CATEGORY, BUILT_IN_EXPERTS, BUILT_IN_RULES, BUILT_IN_TEMPLATES, BaseAdapter, type BaseAdapterConfig, type BaseAdapterOptions, BaseAgent, type BaseAgentOptions, BaseAgentOptionsSchema, BaseCliAdapter, type BaseMcpToolDeps, type BenchmarkAdapter, type BenchmarkComparison, type BenchmarkConfig, type BenchmarkEnvironment, type BenchmarkOperation, type BenchmarkOrchestratorOptions, type BenchmarkReport, type BenchmarkRunContext, type BenchmarkRunSummary, type BenchmarkSuiteResult, type BenchmarkSummary, type BenchmarkThresholds, type BestSolution, BestSolutionSchema, type BottleneckInfo, type BuiltInExpertType, BuiltInExpertTypeSchema, CHECKPOINT_SCHEMA_VERSION, CLAUDE_MODELS, CLAUDE_MODEL_ALIASES, DEFAULT_CACHE_CONFIG as CLI_DEFAULT_CACHE_CONFIG, DEFAULT_CAPABILITIES$1 as CLI_DEFAULT_CAPABILITIES, DEFAULT_COMPOSITE_CONFIG as CLI_DEFAULT_COMPOSITE_CONFIG, CLI_TIMEOUT_PROFILES, CLI_VERSION_REQUIREMENTS, COMPLEXITY_ORDER, CORE_PLUGINS, type CancelJobDeps, type CancelJobInput, CancelJobInputSchema, type CancelJobResponse, type CapabilityProfile, CapacityStatus, type Checkpoint, type PipelineStage as CheckpointPipelineStage, type CheckpointSummary, type FailureCategory as CircuitBreakerFailureCategory, type CircuitProtectedResult, type CircuitState, type ClaimValidation, type ClassifyInput, type ClassifyResult, ClaudeAdapter, type ClaudeAdapterConfig, ClaudeCliAdapter, type ClaudeCliResponse, ClaudeResponseParser, type CliAdapterConfig, type CacheStats as CliCacheStats, type CapabilityProfile$1 as CliCapabilityProfile, type CliCircuitBreakerConfig, CliCircuitBreakerIntegration, type CliCircuitHealthStatus, CliDetectionCache, type CliDetectionCacheConfig, CliDetectionCacheConfigSchema, CliError, CliErrorCode, type ExecutionOptions$1 as CliExecutionOptions, type CliHealthResult, type ModelInfo as CliModelInfo, CliName, CliResponse, type CliRetryLoopConfig, type CliRetryResult, type CliTask, type TaskComplexity as CliTaskComplexity, TokenUsage$1 as CliTokenUsage, CliTransport, type CodeAnalysisResult, type CodeChange, CodeChangeSchema, CodeExpert, type CodeExpertOptions, CodexCliAdapter, type CodexCliResponse, CodexMcpAdapter, CodexResponseParser, type CollaborationConfig, CollaborationConfigSchema, type CollaborationMessage, type CollaborationPattern, CollaborationPatternSchema, type CollaborationResult, CollaborationSession, type CollaborationSessionOptions, type CollectRealVotesOptions, CompactDashboardRenderer, type ComparisonResult, type CompileOptions, type CompileResult$2 as CompileResult, type CompiledGraph, type CompiledPipeline, type CompletionRequest, type CompletionResponse, type ComplexityLevel, ComplexityLevelSchema, type ComplianceStatus, CompositeRouter, type CompositeRouterConfig, CompositeRouterConfigSchema, type CompositeRouterStats, type CompositeRoutingDecision, CompositeRoutingError, type CompositionStep, type CompositionValidation, type ComputedReward, type ConfidenceInterval, ConfigError, type ExpertConfig$1 as ConfigExpertConfig, ExpertConfigSchema$1 as ConfigExpertConfigSchema, type ExpertDefinition$1 as ConfigExpertDefinition, ExpertDefinitionSchema as ConfigExpertDefinitionSchema, type Conflict, type ConflictResolver, type ConflictWarning, ConsensusAlgorithm, ConsensusEngine, ConsensusEngineConfig, ConsensusError, type ConsensusGateNodeOptions, ConsensusMetrics, type ConsensusProposalInput, ConsensusProtocol, ConsensusResult, type ConsensusStats, type ConsensusVerdict, type ConsensusVoteDeps, type ConsensusVoter, type ConsolidatedFinding, type ConsolidationBenchmarkResult, type ConsolidationOperation, type ContentBlock, ContentPriority, type ContextBudget, ContextBudgetSchema, type ContextFilter, ContextFilterSchema, type ContextItem, ContextManager, type ContextManagerConfig, ContextManagerConfigSchema, type ContextPruneStrategy, ContextPruneStrategySchema, ContextPruner, type ContextPrunerConfig, ContextPrunerConfigSchema, type ContextStats, type ContributionScore, type CorePluginRegistrationResult, type CorrelationCoefficient, CorrelationCoefficientSchema, type CorrelationMatrix, CorrelationTracker, type CorrelationTrackerStats, CorrelationTrackerStatsSchema, type CorroborationEvent, type CorroborationResult, type CorroborationRule, type CostEstimate, CostEstimateSchema, type CoverageAnalysis, type CoverageMetrics, CoverageMetricsSchema, type CreateExecutionContextOptions, type CreateExpertDeps, type CreateExpertInput, CreateExpertInputSchema, type CreateExpertOptions, type CreateExpertResponse, type CreateForestInput, type CreateNodeInput, type CreatePROptions, type CreateScmProviderConfig, type CreateSkillOptions, type CreateStreamOptions, type CreateTreeInput, type CriterionFailure, type CriterionResult, CriterionResultSchema, CriterionType, CriterionTypeSchema, type CriterionTypeType, type CrossTreeInfo, CrossTreeInfoSchema, type CrossTreeStrategy, CrossTreeStrategySchema, type CuratedContextItem, type CurationResult, DECEPTION_CATEGORY, DEFAULT_ACTIVATION_OPTIONS, DEFAULT_ADAPTER_LATENCY_CONFIG, DEFAULT_AST_QA_LIMIT, DEFAULT_BENCHMARK_CONFIG, DEFAULT_BUDGET, DEFAULT_COLLECT_STREAM_MAX_CHUNKS, DEFAULT_COMPOSER_CONFIG, DEFAULT_DASHBOARD_CONFIG, DEFAULT_DASHBOARD_RENDER_OPTIONS, DEFAULT_DISTILLER_CONFIG, DEFAULT_ENTRY, DEFAULT_EXECUTION_TIME_MS, DEFAULT_FEEDBACK_COLLECTOR_CONFIG, DEFAULT_FEEDBACK_INTEGRATION_CONFIG, DEFAULT_FIREWALL_POLICY_MODE, DEFAULT_FOREST_CONFIG, DEFAULT_HIGHER_ORDER_CONFIG, DEFAULT_MAX_RETRIES, DEFAULT_MEMORY_BENCHMARK_CONFIG, DEFAULT_OUTCOME_STORAGE_CONFIG, DEFAULT_PATH_SCORING_OPTIONS, DEFAULT_PERMISSIONS, DEFAULT_POLICIES, DEFAULT_PREFERENCE_ROUTER_CONFIG, DEFAULT_RBAC, DEFAULT_RESOURCE_LIMITS, DEFAULT_RETRY_CONFIG, DEFAULT_ROLE_MAPPINGS, DEFAULT_SCENARIOS, DEFAULT_SKILL_LIBRARY_CONFIG, DEFAULT_SKILL_LOADER_CONFIG, DEFAULT_STATISTICAL_OPTIONS, DEFAULT_SWARM_OBSERVER_CONFIG, DEFAULT_TIMEOUTS, DEFAULT_TIMEOUT_PROFILE, DEFAULT_TRINITY_CONFIG, DEFAULT_VOTING_PROTOCOL_CONFIG, DEFAULT_WAVE_CONFIG, DEFAULT_WEIGHTED_VOTING_CONFIG, DEV_PIPELINE_TEMPLATE, type DagEdge, DagEdgeSchema, Dashboard, type DashboardConfig, DashboardConfigSchema, type DashboardFilter, type DashboardFormat, type DashboardHealthIndicators, type DashboardOutcome, type DashboardRenderOptions, type DashboardSnapshot, type DashboardSummary, type DashboardUpdateOptions, type DecomposeError, type DelegateDeps, type DelegateInput, type DelegateInputLike, DelegateInputSchema, type DelegateOutput, DelegateOutputSchema, type DependencyError, type DependencyErrorCode, DependencyErrorCodeSchema, DependencyErrorSchema, DependencyGraph, type DependencyStructure, type DeprecatedVar, type DevPipelineOptions, type DevPipelineResult, type DevPipelineStages, DirectedInteractionGraph, type DistilledRule, type DistillerConfig, type DistillerStats, type DistributionStats, DocumentationExpert, type DocumentationExpertOptions, type DocumentationResult, type DocumentationSection, type DryRunResult, END, EXPERT_CAPABILITIES, EXPERT_DEFAULT_CAPABILITIES, EXPERT_DEFAULT_TEMPERATURES, EXPERT_TYPE_TO_ROLE, type EffectThresholds, type EntrySource, type EnvValidationResult, ErrorCode, type ErrorPayload, type EvaluationCriterion, EvaluationCriterionSchema, EventBus, type EventBusBridgeOptions, type EventBusBridgeResult, type EventBusOptions, type EventFilter, type EventHandler, type EventPayload, type EventType, type ExecuteExpertDeps, type ExecuteExpertInput, ExecuteExpertInputSchema, type ExecuteExpertResponse, type ExecuteSpecDeps, type ExecuteSpecInput, ExecuteSpecInputSchema, type ExecutionContext$1 as ExecutionContext, type ExecutionMode, type ExecutionPhase$1 as ExecutionPhase, type ExecutionPlan$2 as ExecutionPlan, type ExecutionStage, ExpectedOutcome, ExpectedOutcomeSchema, type ExpectedOutcomeType, type ExperienceRecord, type ExperienceStep, type ExperimentDefinition, type ExperimentExport, type ExperimentOutcome, type ExperimentResult, type ExperimentStatus, type ExperimentSummary, type ExperimentVariant, Expert, type ExpertAssignment, ExpertAssignmentSchema, type ExpertBridgeResult, ExpertCollaborationPattern, type ExpertCollaborationPatternType, type ExpertConfig, ExpertConfigSchema, type ExpertDefinition, type ExpertDomain, ExpertDomainSchema, ExpertFactory, ExpertFactoryAdapter, type ExpertInfo, type ExpertMatch, ExpertMatchSchema, type ExpertOptions, ExpertOptionsSchema, type ExpertOutput, ExpertOutputSchema, type ExpertParticipation, ExpertParticipationSchema, type ExpertRecoveryPolicy, type RegisterOptions as ExpertRegisterOptions, ExpertRegistry$1 as ExpertRegistry, type ExpertResult, type ExpertResultSummary, type ExplorationEvent, ExplorationEventSchema, type ExplorationEventType, ExplorationEventTypeSchema, type ExpressionType, type ExtractSymbolsDeps, ExtractSymbolsInputSchema, FALLBACK_SCANNER_DATA, FIREWALL_POLICY_ENV_VAR, FactoryError, type FailureAnalysis, type AnalysisError as FailureAnalysisError, type FailureClassification, type FailurePattern, FailurePatternSchema, type FailureType, type FallbackBehavior, type FallbackEntry, type FeedbackCollectorConfig, FeedbackCollectorConfigSchema, FeedbackIntegration, type FeedbackIntegrationConfig, type FeedbackLoopStats, type FeedbackMessage, type RoutingDecision as FeedbackRoutingDecision, RoutingDecisionSchema as FeedbackRoutingDecisionSchema, FileAuditStorage, type FileReference, FileReferenceSchema, type FiledIssue, type FindingVote, FindingVoteSchema, type Artifact$1 as FirewallArtifact, type PolicyContext$1 as FirewallPolicyContext, type PolicyDecision$2 as FirewallPolicyDecision, type FirewallPolicyEvaluation, type FirewallPolicyMode, FirewallPolicyModeSchema, type PolicyRule$1 as FirewallPolicyRule, type FirewallProcessOptions, type FirewallResult, type Forest, type ForestConfig, ForestConfigSchema, type ForestId, type ForestPruningStrategy, ForestPruningStrategySchema, type ForestResult, ForestResultSchema, type ForestState, ForestStateSchema, type ForestStatistics, ForestStatisticsSchema, type FullCapableProvider, GEMINI_MODELS, GEMINI_MODEL_ALIASES, GENERAL_PIPELINE_TEMPLATE, GeminiAdapter, type GeminiAdapterConfig, GeminiCliAdapter, type GeminiCliResponse, GeminiResponseParser, type GeneratedTest, GeneratedTestSchema, type GetJobResultDeps, type GetJobResultInput, GetJobResultInputSchema, type GetJobResultResponse, type GitHubInput, GitHubProvider, GitHubReviewer, GitHubUserInfo, type GitHubUserMetadata, type GitHubUserRole, GitHubUserRoleSchema, GraphBuilder, type GraphCompileError, type GraphEdge, type GraphEdgeDisplay, type GraphEvent, type GraphExecuteOptions, type GraphExecutionAuditEvent, type GraphExecutionResult, type GraphNode, type GraphPipelineOptions, type GraphPipelineResult, type GraphState, type GraphStats, type GraphSummary, type GraphWorkflowInfo, HARM_EMOTIONAL_CATEGORY, HARM_FINANCIAL_CATEGORY, HARM_PHYSICAL_CATEGORY, HealthStatus, type HigherOrderVotingConfig, HigherOrderVotingConfigSchema, type HigherOrderVotingResult, HigherOrderVotingResultSchema, HigherOrderVotingStrategy, type HookError, HostileInputFirewall, type IAbTestTracker, type IAgent, type IAgenticAdapter, type IArtifactStore, type IAuditLogger, type IAuditStorage, type ICTMConfig, ICTMConfigSchema, type ICTMInferenceResult, ICTMInferenceResultSchema, type ICheckpointStore, type ICircuitBreaker, type ICliAdapter, type ICliCircuitBreakerIntegration, type ICliDetectionCache, type ICliResponseParser, type ICollaborationProtocol, type ICompositeRouter, type IConsensusEngine, type IContextMemoryBackend, type ICorrelationTracker, type IDashboard, type IDashboardRenderer, type IEventBus, type IFeedbackIntegration, type IHigherOrderVoting, type ISwarmObserver as IInteractionObserver, type ILogger, type IMcpNotifier, type IMemoryBackend, type IModelAdapter, INSTRUCTION_SAFETY_CATEGORY, type IOrchestrationObserver, type IOrchestrator, type IOrchestratorFactory, type IOutcomeFeedback, type IOutcomeStorage, type IPipelineStage, type IPluginRegistry, type IPolicyEngine, type IPolicyFirewall, type IPreferenceDataStore, type IRoutingMemory$1 as IRoutingMemory, type ISQLiteDatabase, type ISQLiteStatement, type ISandboxExecutor, type IScmProvider, type IScmReviewer, type IScmUserInfo, type ISkillDependencyGraph, type ISkillLoader, type ITaskTracker, type ITemplateRegistry, type ITokenCounter, type IVotingProtocol, type IVotingStrategy, type IWeightedVoting, type IWorkflowEngine, type IWorkflowRouter, type ImprovementReviewDeps, type ImprovementReviewInput, ImprovementReviewInputSchema, type ImprovementReviewResponse, type ImprovementSuggestion, InMemoryAuditStorage, InMemoryCheckpointStore, InMemoryPreferenceStore, type IndependentSubset, IndependentSubsetSchema, type IneffectiveVar, type InjectionFlag, InjectionFlagSchema, type InputBinding, type InputDefinition, type InputDefinitionInput, type InputDefinitionOutput, InputDefinitionSchema, type InputType, InputTypeSchema, type InteractionEdge, type InteractionGraph, type SwarmObserverConfig as InteractionObserverConfig, SwarmObserverConfigSchema as InteractionObserverConfigSchema, type InteractionOutcome, SwarmObserver as InteractionSwarmObserver, type InvalidVar, type IssueFilters, type IssueReference, IssueReferenceSchema, type IssueTarget, type IssueTriageDeps, type IssueTriageInput, IssueTriageInputSchema, type IssueTriageResponse, type IterativeConsensusConfig, type IterativeConsensusResult, JsonDashboardRenderer, KNOWN_SECTIONS, type KnownSection, type LanguageMatrixEntry, type LatencyMetrics, LatencySampler, type LatencyScenario, type LearningProgress, type LibraryStatistics, type ListExpertsDeps, type ListExpertsInput, ListExpertsInputSchema, type ListExpertsResponse, type ListJobsDeps, type ListJobsInput, ListJobsInputSchema, type ListJobsResponse, type ListWorkflowsDeps, type ListWorkflowsInput, ListWorkflowsInputSchema, type ListWorkflowsResponse, type LoadedSkillSet, LoadedSkillSetSchema, type LogContext, type LogEntry, type LogLevel, type LogPolicyAuditOpts, type LogRateLimitAuditOpts, type LogToolInvocationOpts, type LoggingConfig, LoggingConfigSchema, MANIPULATION_CATEGORY, MAX_AST_QA_LIMIT, MAX_DIFF_LENGTH, MAX_EXECUTION_TIME_MS, MAX_FILES_SCANNED, MEM0_TARGETS, MIN_EXPERTS_FOR_PATTERN, MODEL_CAPABILITIES, type IExpertFactory as McpExpertFactory, type McpLogContext, type McpLogLevel, RateLimiter$1 as McpRateLimiter, type RateLimiterConfig$1 as McpRateLimiterConfig, type MemoryBenchmarkConfig, type MemoryEntry, MemoryError, MemoryImportance, type MemoryMetadata, type MemoryPayload, type MemoryQueryInput, MemoryQueryInputSchema, type MemoryQueryResponse, MemoryStatsInputSchema, type MemoryStatsResponse, type MemoryWriteInput, MemoryWriteInputSchema, type MemoryWriteResponse, type MergePROptions, type Message, type MessagePayload, type MessageRole, ModelCapability, type ModelConfig, ModelConfigSchema, type ModelEntry, ModelError, type ModelMetrics, type ModelPerformanceSummary, type ModelPreference, ModelPreferenceSchema, ModelRegistry, type ModelRegistryOptions, type ModelSelection, ModelSelectionSchema, type ModelTiers, ModelTiersSchema, NOOP_NOTIFIER, NOOP_PROGRESS, NexusError, type NexusErrorOptions, NoAdapterError, type NodeHandler$1 as NodeHandler, type NodeHandlerFactory, type NodeHook, type NodeHookContext, type NodeId, type NodeResult, type NodeState, NodeStateSchema, OLLAMA_MODELS, OPENAI_MODELS, OPENAI_MODEL_ALIASES, OWVoting, type OWVotingOptions, type AgentState$1 as ObserverAgentState, type CostMetrics as ObserverCostMetrics, type RoutingDecision$2 as ObserverRoutingDecision, type SessionMetrics as ObserverSessionMetrics, type SessionTokenTotals as ObserverTokenUsage, type TrackedAgent as ObserverTrackedAgent, OllamaAdapter, type OllamaAdapterConfig, OpenAIAdapter, type OpenAIAdapterConfig, OpenCodeCliAdapter, type OperationBenchmark, type OperationComparison, type OrchestrateDeps, type OrchestrateInput, type OrchestrateInputLike, OrchestrateInputSchema, type OrchestrateOutput, OrchestrateOutputSchema, OrchestrationError, type OrchestrationObserverEvent, type OrchestrationObserverListener, type OrchestrationStats, OrchestrationUnavailableError, Orchestrator, type OrchestratorDefinition, OrchestratorError, type OrchestratorErrorCode, type OrchestratorExecuteOptions, OrchestratorFactory, type OrchestratorFactoryConfig, type OrchestratorOptions, OrchestratorOptionsSchema, type OrchestratorResult, type OrchestratorStep, type OrchestratorType, type OutcomeClass, type OutcomeFailureCategory, OutcomeFailureCategorySchema, OutcomeFeedbackCollector, type OutcomeProcessedCallback, type OutcomeRecord, type OutcomeStorageConfig, OutcomeStorageConfigSchema, OutcomeStorageError, OutcomeStore, type OutcomeStoreConfig, type TaskOutcome$1 as OutcomeTaskRecord, TaskOutcomeSchema$1 as OutcomeTaskSchema, PIPELINE_EVENT_TYPES, PIPELINE_STATE_KEYS, PIPELINE_TEMPLATES, PLUGIN_TRUST_LEVELS, PRIVACY_CATEGORY, PROMPT_DEFINITIONS, PR_REVIEW_ROLES, type PairwiseVotingHistory, PairwiseVotingHistorySchema, type ParallelOptions, ParallelProtocol, ParseError, type ParsedExpression, type ParsedSpec, ParsedSpecSchema, type ParsedTemplate, type PathAccessRule, type PathScore, type PathScoreBreakdown, PathScoreBreakdownSchema, PathScoreSchema, type PathScoringOptions, type PatternMetrics, type PatternOutcome, type PatternType, type PerformanceMatrixEntry, type PerformanceSummary, type PersistentDistillerConfig, PersistentOutcomeStore, type PersistentOutcomeStoreConfig, PersistentStrategyDistiller, type PipelineBridgeResult, type PipelineCheckpointState, type PipelineContext, type PipelineDeps, type PipelineEdge, type PipelineError, type PipelineEvent, type PipelineEventType, type PipelineExecuteOptions, type PipelineGraphResult, type PipelineMetrics, type PipelineMode, type PipelinePlugin, type PolicyMode as PipelinePolicyMode, type PolicyViolation as PipelinePolicyViolation, type PipelineResult, type PipelineRole, PipelineRunner, type PipelineStage$1 as PipelineStage, type PipelineStageData, type PipelineTask, type PipelineTemplate, type PipelineType, type PlanCompileOptions, type PlanContract, PlanContractSchema, type PluginManifest, PluginManifestSchema, PluginRegistry, type PluginRegistryOptions, type PluginTrustLevel, type ValidationError as PluginValidationError, type PolicyConfig, PolicyConfigSchema, type PolicyContext, type PolicyDecision, type PolicyDecisionAuditOpts, PolicyEngine, PolicyError, type PolicyEvalResult, type PolicyEvaluation, type PolicyEvaluatorOptions, PolicyFirewall, type PolicyFirewallConfig, type PolicyGateEvent, type PolicyGateSpec, PolicyGateSpecSchema, type PolicyMode$1 as PolicyMode, type PolicyRule, type PolicyViolation$1 as PolicyViolation, type PrReviewDecision, type PrReviewDeps, type PrReviewInput, PrReviewInputSchema, type PrReviewResponse, type PrReviewVote, type PreconditionConfig, type PreconditionOutcome, type PreconditionResult, type PreferenceDataPoint, type PreferenceFilter, type PreferenceModelStats, type PreferencePrediction, type PreferenceRecord, PreferenceRouter, type PreferenceRouterConfig, PreferenceRouterConfigSchema, type PreferenceRoutingDecision, type PreferenceSignal, type PreferredCapability, type ProbeFn, type ProbeResult, type PromptCachingMode, type PromptDefinition, type PromptMessage, type PromptRegistrationResult, ProofOfLearningStrategy, Proposal, ProposalId, ProposalState, ProposalStatus, ProtocolFactory, type ProtocolOptions, type ProvenanceEntry, type ProviderConfig, ProviderConfigSchema, type PruneOptions, type PruneResult, PruningStrategy, type QaReviewResult, type QualityAttribute, type QualityMetrics, type QualityRequirement, type QualityScorer, type QualitySignals, QualitySignalsSchema, QueryFeatureExtractor, type QueryFeatures, type QueryOptions, type QueryTraceInput, QueryTraceInputSchema, RISK_AWARENESS_CATEGORY, ROBUSTNESS_CATEGORY, ROLE_DEFAULT_TRUST, type RateLimitAuditOpts, RateLimitError, type RateLimitExceeded, type RateLimiterState, type ReasoningDepth, ReasoningDepthSchema, type ReasoningNode, type ReasoningNodeMetadata, ReasoningNodeMetadataSchema, ReasoningNodeSchema, type ReasoningStepType, ReasoningStepTypeSchema, type ReasoningTree, ReasoningTreeSchema, type RecordExecutionOptions, type RecordInteractionOptions, type RecordOutcomeParams, RecoverableExpert, type RegistrationError, RegistryAlreadyInitializedError, RegistryError, type RegistryImportInput, RegistryImportInputSchema, type RegistryRelationship, type RegistryScanner, type RegistrySnapshot, type RegistryStats, type RegretAnalysis, type RepoAnalysis, type RepoAnalyzeDeps, type RepoAnalyzeInput, RepoAnalyzeInputSchema, type RepoSecurityPlan, type RepoSecurityPlanDeps, type RepoSecurityPlanInput, RepoSecurityPlanInputSchema, type ReportOptions, type ReputationAssessment, ReputationCache, type ReputationEvent, type ReputationGateDecision, type ReputationGatingMode, type ResearchAddDeps, type ResearchAddInput, ResearchAddInputSchema, type ResearchAddResponse, type ResearchAddSourceDeps, type ResearchAddSourceInput, ResearchAddSourceInputSchema, type ResearchAddSourceResponse, type ResearchAnalyzeDeps, type ResearchAnalyzeInput, ResearchAnalyzeInputSchema, type ResearchAnalyzeResponse, type ResearchCatalogReviewDeps, ResearchCatalogReviewInputSchema, type ResearchDiscoverDeps, type ResearchDiscoverInput, ResearchDiscoverInputSchema, type ResearchDiscoverResponse, type ResearchQueryDeps, type ResearchQueryInput, ResearchQueryInputSchema, type ResearchQueryResponse, type ResearchSynthesizeDeps, type ResearchSynthesizeInput, ResearchSynthesizeInputSchema, type ResearchTriggerConfig, type ResolveResult, type ResolvedPipelineDeps, type ResourceLimits, type ResourceMetrics, type ResourceUsage, type Result, ResultAggregator, type ResultConflict, type ResultSubmissionMessage, type ResultSummary, type RetryAttemptInfo, type RetryConfig, RetryExhaustedError, type ReviewCapableProvider, ReviewProtocol, type ReviewRequestMessage, type ReviewResponseMessage, ReviewResponseMessageSchema, RiskLevel, RiskLevelSchema, type RiskLevelType, type RoleSkillMapping, type RoundSummary, type RouterType, type DashboardConfig$1 as RoutingDashboardConfig, type RoutingDecisionRecord, RoutingMemoryError, type RoutingMemoryExport, type RoutingMemoryStats$1 as RoutingMemoryStats, type RoutingMetrics, RoutingMetricsCollector, type RoutingMetricsConfig, type RoutingRecord, type RuleStatus, type RulesSnapshot, RulesSnapshotSchema, type RunAgentArgs, type RunAstQaRulesOptions, type RunGraphWithConsensusOptions, type RunGraphWorkflowDeps, type RunGraphWorkflowInput, RunGraphWorkflowInputSchema, type RunGraphWorkflowResponse, type RunWorkflowDeps, type RunWorkflowInput, RunWorkflowInputSchema, SAFETY_CATEGORIES, SAFETY_CATEGORY_MAP, PROVIDER_ENV_KEYS as SDK_PROVIDER_ENV_KEYS, DEFAULT_CAPABILITIES as SKILL_DEFAULT_CAPABILITIES, SKILL_PERMISSIONS, SQLiteOutcomeStorage, STAGE_TYPES, START, type SafetyCategory, SafetyCategoryId, SafetyCategoryIdSchema, type SafetyCategoryIdType, SafetyCategorySchema, type SafetyTaxonomySummary, type SafetyTestCase, SafetyTestCaseSchema, type SandboxConfig, type SandboxExecutionOptions, type SandboxMode, type SandboxPolicy, type SandboxResult, type SanitizationEvent, type SanitizedInput, SanitizedInputSchema, type SanitizerConfig, SanitizerConfigSchema, type ScannerData, type ScannerEntry, type ScannerRecommendation, type ScannerRegistryManifest, type ScenarioError, type ScenarioResult, ScenarioResultSchema, type ScmComment, type ScmCommentDetail, ScmError, type ScmFileChange, type ScmIssue, type ScmIssueDetail, type PRStatus as ScmPRStatus, type ScmPlatform, type ScmPullRequest, type ScmPullRequestDetail, type ScmReviewDecision, type ScmToken, type ScmUserMetadata, type ScoreBreakdown, ScoreBreakdownSchema, SdkAdapter, type SdkAdapterConfig, type SdkProviderId, type SearchCodebaseDeps, SearchCodebaseInputSchema, type SearchUsagesDeps, SearchUsagesInputSchema, type SecurityAnalysisResult, type AuditEvent as SecurityAuditEvent, type AuditQuery as SecurityAuditQuery, type SecurityCapability, type SecurityConfig, SecurityConfigSchema, SecurityError, type SecurityErrorCode, SecurityErrorCodeSchema, type SecurityEventAuditOpts, SecurityExpert, type SecurityExpertOptions, type SecurityFocusArea, type PolicyDecision$1 as SecurityPolicyDecision, SelectionError, type ExpertRegistry as SelectionExpertRegistry, type SelectionOptions, SelectionOptionsSchema, type SelectionResult$1 as SelectionResult, SelectionResultSchema, SequentialProtocol, type SerializedError, type ServerConfig, type ServerError, type ServerInstance, type SessionEvent, type SessionState, type SessionStatus, SessionStatusSchema, type SharedConclusion, SharedConclusionSchema, type SharedInsight, SharedInsightSchema, SimpleAgent, SimpleMajorityStrategy, type Skill, AgentRoleSchema$2 as SkillAgentRoleSchema, type SkillAttestation, SkillAttestationSchema, type SkillCapabilities, SkillCapabilitiesSchema, type SkillCategory, type SkillComplexity, SkillComposer, type SkillComposerConfig, type SkillComposition, type SkillCompositionRequest, type SkillDependency, SkillDependencyGraph, SkillDependencySchema, type SkillDependencyType, SkillDependencyTypeSchema, type SkillExample, type SkillExecution, type SkillExecutionStatus, SkillLibrary, type SkillLibraryConfig, SkillLoader, type SkillLoaderConfig, SkillLoaderConfigSchema, type SkillLoaderError, type SkillLoaderErrorCode, SkillLoaderErrorSchema, type SkillMetrics, type SkillParameter, type SkillPermission, SkillPermissionSchema, type SkillProvenance, SkillProvenanceSchema, type SkillQuery, type SkillRBAC, SkillRBACSchema, type SkillSearchResult, type SkillSecurityError, SkillSecurityErrorSchema, type SkillStore, type SkillWithMetrics, type SourceCitation, SourceCitationSchema, type SpanId, type SpecExecutionError, type SpecExecutionOptions, type SpecExecutionResult, type SpecParseError, type StageCompletedOptions, type StageContext, type StageFailedOptions, type StageOutput, type StageRegistry, type StageResult, StageResultSchema, type StageSpec, StageSpecSchema, type StageStartedOptions, type StageType, type StateChangeCallback, type StateChangePayload, type StateFieldSchema, type StateMachineOptions, type StateReducer, type StateSchema, type StateTransition, type StateTransitionEvent, type StatisticalOptions, type StatusUpdateMessage, type StepExecutionOptions, type StepExecutor$1 as StepExecutor, type StepExecutorDeps, type StepResult, type StepResultSummary, type StopReason, type StoredModelStats, type StoredReward, type StoredRoutingDecision, type StoredTaskOutcome, type StrategyAction, StrategyDistiller, StreamCancelledError, type StreamChunk, StreamController, StreamError, type StreamState, AgentRoleSchema$1 as StrictAgentRoleSchema, InputDefinitionSchema$1 as StrictInputDefinitionSchema, WorkflowDefinitionSchema$1 as StrictWorkflowDefinitionSchema, WorkflowStepSchema$1 as StrictWorkflowStepSchema, type StrippedElement, StrippedElementSchema, type SubTask, SubTaskSchema, SubprocessCliAdapter, type SubtaskNode, SubtaskNodeSchema, type SubtaskPriority, SubtaskPrioritySchema, type SubtaskStatus, SubtaskStatusSchema, type SubtaskType, SubtaskTypeSchema, SupermajorityStrategy, type SuspiciousSignal, SuspiciousSignalSchema, type AgentState as SwarmAgentState, type SwarmHealthMetrics$1 as SwarmHealthMetrics, type SycophancyIndicator, type SycophancyReport, type SynthesizedResult, SynthesizedResultSchema, type SystemComponent, TASK_STATUSES, TASK_TYPE_EXPERTS, TEMPLATE_CATEGORIES, TEMPLATE_KEYWORDS, TRINITY_ROLE_MAX_TOKENS, TRINITY_ROLE_PROMPTS, TRINITY_ROLE_TEMPERATURES, TRUST_TIER_NUMERIC, type Task$1 as Task, type TaskAnalysis, TaskAnalysisSchema, type TaskAssignmentMessage, type TaskClassification, type TaskCommitment, type TaskContext, type TaskContract, TaskContractSchema, type TaskDag, TaskDagSchema, type TaskId, type TaskOutcome, type TaskOutcomeRecord, TaskOutcomeSchema, type TaskPayload, type TaskProfileSummary, TaskQueue, type TaskRequirements, type TaskResult, type TaskRoutingEntry, TaskSchema, type TaskSignals, type TaskStatus, type TaskTypePerformance, type TemplateCategory, TemplateCategorySchema, type TemplateMetadata, TemplateMetadataSchema, TemplateRegistry, type TerminationReason, TerminationReasonSchema, type TestQuality, type TestingAnalysisResult, TestingExpert, type TestingExpertOptions, type TextContent, TextDashboardRenderer, type ThinkerOutput, type ThroughputMetrics, type TimeConstraint, type TimePeriod, TimeoutError, type TimeoutProfile, type TokenBenchmarkResult, TokenCountError, type TokenCountResult, TokenCounter, type TokenCounterConfig, TokenCounterProvider, type TokenMetrics, type TokenResolverConfig, type TokenStrategy, type TokenUsage, type ToolCompletedEvent, type ToolDefinition, type ToolDefinitionFormat, type ToolInvocationAuditOpts, type ToolInvokedEvent, type ToolPayload, type ToolRegistrationOptions, type ToolRegistrationResult, type ToolResult$1 as ToolResult, type ToolSet, ToolSetSchema, type TraceId, type TrackedTask, type TransitionErrorCallback, type TreeId, type TreeState, TreeStateSchema, type TreeStatistics, TreeStatisticsSchema, type Trend, type TrinityConfig, TrinityConfigSchema, TrinityCoordinator, type TrinityExecuteOptions, type TrinityPhase, type TrinityPhaseResult, TrinityPhaseSchema, type TrinityResult, type TrinityRole, type TrinityRoleConfig, TrinityRoleSchema, TrinityStopReasonSchema, type TrustClassificationEvent, type TrustTier, TrustTierSchema, UnanimousStrategy, UnifiedAdapterRegistry, type UnifiedRegistryConfig, type UnknownVar, type Unsubscribe, type V2Config, type V2Mode, VERSION, VOTING_THRESHOLDS, ValidationDashboard, ValidationError$1 as ValidationError, type ValidationIssue, type VariantStats, type VerificationResult, type VerifierOutput, VerifierVerdictSchema, type VersionRequirements, VersionStatus, type Violation, ViolationSchema, Vote, VoteCounts, type VoteDecision, VoteDecisionSchema, type VoteMessage, VoteMessageSchema, type VoteResult, type VotingObservation, VotingObservationSchema, type VotingOutcome, VotingProtocol, type VotingProtocolConfig, VotingProtocolConfigSchema, type VotingProtocolResult, type VotingRound, type VotingRoundPhase, VotingRoundPhaseSchema, type VotingRoundStatus, VotingRoundStatusSchema, type VotingSession, VotingStrategyFactory, type Vulnerability, VulnerabilitySchema, VulnerabilitySeveritySchema, type WaveExecutionResult, type WaveResult, WaveScheduler, type WaveSchedulerConfig, type WaveTask, type WaveTaskExecutor, type WaveTaskResult, WeatherReportInputSchema, type WeightedAgentRecord, type WeightedConsensusResult, WeightedVoteCounts, WeightedVoting, type WeightedVotingConfig, type WeightedVotingOptions, type WinLossAnalysis, type WithRetryOptions, type WorkChunk, type WorkerOutput, type WorkflowAdapterConfig, type WorkflowConfig, WorkflowConfigSchema, type WorkflowDefinition, type WorkflowDefinitionInput, type WorkflowDefinitionOutput, WorkflowDefinitionSchema, type WorkflowEngineFactoryConfig, WorkflowError, type WorkflowExecutionContext, type ExecutionPlan$1 as WorkflowExecutionPlan, type IExpertFactory$1 as WorkflowExpertFactory, type WorkflowInfo, WorkflowInputsSchema, WorkflowOrchestratorAdapter, type WorkflowPattern, type WorkflowRouterOptions, type RoutingDecision$1 as WorkflowRoutingDecision, type WorkflowStep$1 as WorkflowStep, type WorkflowStepInput, type WorkflowStepOutput, WorkflowStepSchema, type WorkflowTemplate, type WorkflowToolResult, actorFromContext, aggregatePrDecisions, aggregateResults, analyzeTask as analyzeDelegateTask, analyzeFailures, analyzeGitHubRepo, analyzeRepo, append, areStepsCompleted, assessReputation, bufferStream, buildDependencyGraph, buildFinalResult, buildPendingResult, buildPlanFromAnalysis, buildPrReviewProposal, buildDependencyGraph$1 as buildSkillDependencyGraph, buildTimeoutResult, calculateDelay, calculateDistributionStats, calculateMetricsTotals, calculateMinSampleSize, calculateRegret, calculateRoutingDistribution, calculateTokenCost, calculateTokenMetrics, calculateVoteWeight, calculateWinLoss, canExecuteSkill, canInfluenceDecisions, canProceed, cancelExecution, categorizeOutcomeError, categorizeOutcomeErrorMessage, checkForResearchTriggers, checkPermissionBoundary, checkPipelinePolicy, checkpointToResult, chunkByDirectory, classifyExpertFailure, classifyTask, classifyTrust, cleanupCheckpoint, clearRegistryCache, clearTemplateCache, calculateBackoffDelay as cliCalculateBackoffDelay, categorizeError as cliCategorizeError, closeServer, collectAstQaFindings, collectRealVotes, collectStream, compareBenchmarks, compareProportions, compilePipelineGraph, compilePlan, compileSpecToGraph, computeAdaptiveThresholds, computeOutcomeReward, concatStreams, connectTransport, containsExpressions, countActiveSessions, createAbTestTracker, createAgentPairKey, createAgentStages, createStepExecutor as createAgentStepExecutor, createAgenticAdapter, createAllAdapters, createArchitectureExpert, createAttestation, createAuditLogger, createAuditTrail, createBenchmarkSummary, createCheckpoint, createCheckpointStore, createClaudeAdapter, createCliAdapter, createCliCircuitBreakerIntegration, createCliDetectionCache, createCodeExpert, createCollaborationSession, createCompositeRouter, createConsensusEngine, createConsensusGateNode, createContextItem, createCorePluginRegistry, createCorrelationTracker, createDashboard, createDashboardRenderer, createDecayOp, createDefaultDeps, createDefaultPolicyEngine, createDefaultPolicyFirewall, createDefaultRateLimiter, createDefaultRegistry, createDelegatePipeline, createDependencyError, createDevStageRegistry, createDocumentationExpert, createDryRunHandler, createEventBusBridge, createExecutionContext, createExecutionPlan, createFeedbackIntegration, createFeedbackSubscriber, createFullGitHubProvider, createGeminiAdapter, createGitHubAdapter, createGitHubProvider, createGraphAuditBridge, createHigherOrderVotingStrategy, createInitialCostMetrics, createInitialSessionMetrics, createInitialTokenUsage, createInitializedWorkflowEngine, createInteractionGraph, createSwarmObserver as createInteractionSwarmObserver, createIsolatedRegistry, createLogger, createMcpLogger, createMcpNotifier, createOWVoting, createOllamaAdapter, createOpenAIAdapter, createOrchestrator, createOrchestratorFactory, createOutcomeFeedbackCollector, createOutcomeStorage, createPolicyContext, createPreferenceRouter, createProductionWorkflowEngine, createPromotionOp, createProtocolFactory, createRateLimiter, createRealWorkflowEngine, createResultAggregator, createRoutingDecision, createRoutingMetricsCollector, createSandboxExecutor, createScmProvider, createSecurityError, createSecurityExpert, createServer, createSkillComposer, createSkillDependencyGraph, createSkillLibrary, createSkillLoader, createStateComparisonVerifier, createStateGuard, createStateMachine, createStrategyDistiller, createStrategyFactory, createStream, createTaskOutcome, createTaskQueue, createTemplateRegistry, createTestingExpert, createTimer, createTokenCounter, createToolLogger, createTrackedAgent, createTrinityCoordinator, createUnifiedRegistry, createValidationDashboard, createValidator, createVotingProtocol, createWaveScheduler, createWeightedVoting, createWorkflowEngineDeps, createWorkflowEngineDepsAsync, createWorkflowRouter, curateContext, customReducer, decomposeSpec, defaultConfig, delegateInputToTaskContract, denyMutationsWithoutModeRule, deriveEntry, detectFailurePatterns, detectLatencyPatterns, detectSuccessPatterns, detectTrend, determineFinalStatus, effectFor, emitCorroborationEvent, emitExecutionComplete, emitGraphExecutionEvent, emitNodeResults, emitNodeStarted, emitPipelineStageEvent, emitPolicyEvent, emitReputationEvent, emitSanitizationEvent, emitStageCompleted, emitStageFailed, emitStageStarted, emitStateUpdated, emitStepCompleted, emitTrustEvent, ensurePolyglotLangs, err, estimateTokens as estimateBenchmarkTokens, estimateTaskComplexity, estimateTokens$1 as estimateTokens, evaluatePipelinePolicy, evaluatePolicy$1 as evaluatePolicy, evaluatePolicy as evaluateSecurityPolicy, executeCliRetryLoop, executeDelegatePipeline, executeExpert, executeGraph, executeOrchestratePipeline, executeParallel, executeSpec, extractBooleanField, extractExpressions, extractNonErrorMessage, extractNumberField, extractSessionId, extractStateValue, extractStringArrayField, extractStringField, filterAvailableModels, filterStream, findActiveSession, findMissingDependencies, flushPipelineMemory, formatAdapterLatencyReport, formatBenchmarkReport, formatBenchmarkResults, formatComparisonResults, formatCompileError, fromArray, generateATL, generateBenchmarkReport, generateProposalId, generateSecurityPlan, generateWeatherReport, getAllTestCases, getAvailabilityCache, getAvailableClis, getAvailableRoles, getBenchmarkEnvironment, getBuiltInAstRulesPath, getBuiltInTemplates, getBuiltInTemplatesPath, getBuiltInTemplatesWithMetadata, getCapabilitiesForRole, getCategoriesByMinRiskLevel, getCliForModelId, getCompletedSteps, getCorroborationRules, getDefaultAvailableModelsCache, getDefaultRegistry, getEventBusStats, getExecutionDuration, getExecutionOrder, getExpertRegistry, getFallbackChain, getGlobalRegistry, getGraphRegistry, getGraphWorkflowList, getKnownNexusVarNames, getOutcomeStore, getPipelineArtifactStore, getPipelinePluginRegistry, getPolicy, getPolicyMode, getRecommendedRole, getReferencedSteps, getRegistryManifest, getRequiredTrustTier, getSafetyCategory, getSafetyTaxonomySummary, getSkillSetForTask, getSkillsForTask, getStepResult, getSwarmObserver, getTemplate, getTestCasesByTags, getTimeoutForTask, getTimeoutForTaskAuto, getTokenEnvVars, getTopologicalOrder, getVariable, hasToken, ictmToExpertConfig, identifySessionsToRemove, inferICTM, initializeAgentSkills, initializeBuiltInTemplates, initializeEventBusBridge, isCancelled, isCliAvailable, isRetryableError as isCliRetryableError, isErr, isMutatingAction, isOk, isReadOnlyAction, isRetryableError$1 as isRetryableError, isStepCompleted, isZodError, listTemplateIds, loadCheckpointState, loadRules, loadTemplateFile, loadTemplatesFromDirectory, loadWorkflowFile, logPolicyAudit, logRateLimitAudit, logToolError, logToolInvocationAudit, logToolStart, logToolSuccess, logger, map, mapAuthorAssociation, mapErr, mapVoteDecisionToPrDecision, meanConfidenceInterval, mergeStreams, normalizeRepoId, ok, orchestrateInputToTaskContract, overwrite, parseATL, parseAgentPairKey, parseExpression, parseSpec, parseTemplateContent, parseWorkflowJson, parseWorkflowYaml, proportionConfidenceInterval, quickSelect, reduceStream, registerCancelJobTool, registerConsensusVoteTool, registerCorePlugins, registerCreateExpertTool, registerDelegateToModelTool, registerExecuteExpertTool, registerExecuteSpecTool, registerExpertsResource, registerExtractSymbolsTool, registerGetJobResultTool, registerImprovementReviewTool, registerIssueTriageTool, registerListExpertsTool, registerListJobsTool, registerListWorkflowsTool, registerMemoryQueryTool, registerMemoryStatsTool, registerMemoryWriteTool, registerModelsResource, registerOrchestrateTool, registerPrReviewTool, registerPrompts, registerQueryTraceTool, registerRegistryImportTool, registerRepoAnalyzeTool, registerRepoSecurityPlanTool, registerResearchAddSourceTool, registerResearchAddTool, registerResearchAnalyzeTool, registerResearchCatalogReviewTool, registerResearchDiscoverTool, registerResearchQueryTool, registerResearchResource, registerResearchSynthesizeTool, registerResources, registerRunGraphWorkflowTool, registerRunWorkflowTool, registerSearchCodebaseTool, registerSearchUsagesTool, registerTools, registerWeatherReportTool, requiresCitation, requiresCorroboration, requiresHumanApproval, resetAvailabilityCache, resetGlobalRegistry, resetPipelineArtifactStore, resetPipelinePluginRegistry, resetRegistry, resolveExpression, resolveFallback, resolveFirewallPolicyMode, resolveInput, resolvePipelineDeps, resolveReputationGatingMode, resolveScannerData, resolveStringExpressions, resolveToken, resolveV2Config, resolveWithFallbacks, resultToOutcome, runAdapterLatencyBenchmark, runAdaptiveOrchestrator, runAstQaRules, runBenchmark, runConsensusGate, runConsolidationBenchmark, runDevPipeline, runGraphPipeline, runGraphWithConsensus, runIterativeConsensus, runMemoryBenchmarks, runOperationBenchmark, runPreconditions, runTokenBenchmark, runVerification, safePathsRule, safeValidateExpertConfig, sanitize, sanitizeInput, saveStageCheckpoint, scoreByHybrid, scoreByImportance, scoreByRecency, secretPathsRule, selectExperts, selectModel, setDefaultAvailableModelsCache, setDefaultRegistry, setSwarmObserver, setVariable, sigmoidConfidence, skip, sleep, snapshotContext, startStdioServer, storeStepResult, take, takeUntil, tapStream, toSuiteResult, toolError, toolSuccess, toolSuccessStructured, transformStream, unwrap, unwrapOr, validateAgentAction, validateCommand, validateCorroboration, validateDependencyGraph, validateEvaluationCriterion, validateExpertConfig, validateExpressions, validateICTM, validateNexusEnv, validateRequiredInputs, validateSafetyCategory, validateScenario, validateCapabilities as validateSkillCapabilities, validateSkillExecution, validateSkillProvenance, validateRBAC as validateSkillRBAC, validateTestCase, validateToolInput, validateWorkflow, validateWorkflowDependencies, withLogging, withRetry, withRetryWrapper, withTimeout };