/**
 * Crewly Agent Runtime Service
 *
 * Concrete RuntimeAgentService subclass for the Crewly Agent.
 * Supports two execution modes:
 * - **In-process** (default): AgentRunner runs in the main Node.js process
 * - **Worker process**: AgentRunner runs in a child process via fork(),
 *   enabling hot-reload and crash isolation
 *
 * @module services/agent/crewly-agent/crewly-agent-runtime.service
 */
import { RuntimeAgentService } from '../runtime-agent.service.abstract.js';
import { AgentRunnerService } from './agent-runner.service.js';
import { type RuntimeType } from '../../../constants.js';
import type { CrewlyAgentConfig, AgentRunResult } from './types.js';
import { SessionCommandHelper } from '../../session/index.js';
/**
 * Crewly Agent runtime with optional worker process isolation.
 *
 * Supports two modes:
 * - **In-process** (default): AgentRunner runs directly in the main process
 * - **Worker process** (`useWorkerProcess: true`): AgentRunner runs in a
 *   forked child process, enabling hot-reload and crash isolation
 *
 * @example
 * ```typescript
 * // In-process mode (default)
 * const runtime = new CrewlyAgentRuntimeService(sessionHelper, projectRoot);
 * await runtime.initializeInProcess('crewly-orc');
 *
 * // Worker process mode
 * const runtime = new CrewlyAgentRuntimeService(sessionHelper, projectRoot);
 * await runtime.initializeInProcess('crewly-orc', { useWorkerProcess: true });
 *
 * // Hot-reload: restart worker with fresh code, preserving session
 * await runtime.hotReload();
 * ```
 */
export declare class CrewlyAgentRuntimeService extends RuntimeAgentService {
    private agentRunner;
    private initialized;
    private currentSessionName;
    private currentMemberId;
    private currentModelString;
    private logBuffer;
    private rateLimiter;
    private heartbeatTimer;
    /** AbortController for the currently executing message — enables external abort */
    private messageAbortController;
    /** Whether this instance uses a worker process instead of in-process execution */
    private useWorkerProcess;
    /** The forked worker child process */
    private workerProcess;
    /** Stored config for hot-reload — needed to re-init the worker */
    private storedConfig;
    /** Pending promise resolver for the current worker run */
    private workerRunResolve;
    /** Pending promise rejector for the current worker run */
    private workerRunReject;
    /** Whether the worker is currently processing a message */
    private workerProcessing;
    constructor(sessionHelper: SessionCommandHelper, projectRoot: string);
    /**
     * Get the runtime type identifier.
     *
     * @returns 'crewly-agent' runtime type constant
     */
    protected getRuntimeType(): RuntimeType;
    /**
     * Detect if the Crewly Agent runtime is running.
     * For in-process runtime, this checks if the AgentRunner is initialized.
     *
     * @param _sessionName - Session name (unused for in-process runtime)
     * @returns True if the agent runner is initialized
     */
    protected detectRuntimeSpecific(_sessionName: string): Promise<boolean>;
    /**
     * Get patterns that indicate the runtime is ready.
     * For in-process runtime, there are no terminal patterns — readiness is checked programmatically.
     *
     * @returns Empty array (no terminal output to match)
     */
    protected getRuntimeReadyPatterns(): string[];
    /**
     * Get patterns that indicate runtime errors.
     *
     * @returns Empty array (errors are thrown as exceptions, not terminal patterns)
     */
    protected getRuntimeErrorPatterns(): string[];
    /**
     * Get patterns that indicate the runtime has exited.
     *
     * @returns Empty array (in-process runtime doesn't exit via terminal)
     */
    protected getRuntimeExitPatterns(): RegExp[];
    /**
     * Initialize the agent runtime.
     *
     * Loads the system prompt from config/roles/orchestrator/prompt.md,
     * creates the AgentRunnerService (in-process or worker), and initializes the model.
     *
     * Onboarding v3 (B3): when the role is `'orchestrator'` and the cold-start
     * detector ({@link OnboardingBootstrapService}) reports a fresh OSS install,
     * the runtime swaps the role prompt for the onboarding-mode prompt
     * ({@link loadOnboardingPrompt}) and flips persisted state to
     * `mode: 'onboarding'`. The state-persistence checkpoint is saved before
     * the AgentRunner initialises so a crash mid-init still resumes correctly.
     *
     * @param sessionName - Session name for this agent instance
     * @param config - Optional partial config overrides. Set `useWorkerProcess: true` to run in a child process.
     * @param roleName - Role name for system prompt lookup (default: 'orchestrator')
     */
    initializeInProcess(sessionName: string, config?: Partial<CrewlyAgentConfig> & {
        useWorkerProcess?: boolean;
    }, roleName?: string): Promise<void>;
    /**
     * Decide whether this orc bootstrap should enter onboarding mode.
     *
     * Returns false (no-op) for non-orchestrator roles, when the bootstrap
     * service hasn't been wired yet, or when detection throws — fail-closed
     * so transient errors never falsely trigger onboarding.
     *
     * Side effects: when true, flips the persisted orchestrator mode to
     * `'onboarding'` and saves a checkpoint immediately, so a crash before
     * the AgentRunner finishes initialising still resumes in onboarding mode.
     *
     * @param roleName - The resolved role name for this bootstrap
     * @returns True iff cold-start fired and the prompt should be swapped
     */
    private detectOnboardingMode;
    /**
     * Best-effort `firstLaunchedAt` marker write for the project at
     * `projectPath`.
     *
     * Resolves the project record by matching `Project.path` against the
     * given path, then delegates to `OnboardingBootstrapService.markProjectAsLaunched`.
     * No-op if the bootstrap service isn't wired or if no project record
     * matches (fresh installs without an explicit project bind never reach
     * this branch — the orc bootstrap doesn't pass `projectPath` then).
     *
     * @param projectPath - Absolute filesystem path of the bound project
     */
    private markFirstLaunchForCwd;
    /**
     * Handle an incoming message by routing it to the AgentRunner.
     *
     * This is the primary entry point for message delivery, replacing
     * the PTY write path used by other runtimes.
     *
     * @param message - The message to process
     * @param metadata - Optional metadata (e.g. Slack channelId, threadTs)
     * @returns Agent run result with text response and tool call records
     * @throws Error if the runtime is not initialized
     */
    handleMessage(message: string, metadata?: Record<string, string>): Promise<AgentRunResult>;
    /**
     * Execute a single message against the AgentRunner.
     *
     * Separated from handleMessage to allow the rate limiter to wrap this
     * with throttling, coalescing, and 429 retry logic.
     *
     * @param session - Session name
     * @param cleanMessage - Message content (prefix already stripped)
     * @param conversationId - Optional conversation ID
     * @param metadata - Optional metadata
     * @returns Agent run result
     */
    private executeMessage;
    /**
     * Record token usage to the TokenUsageService if tracking is enabled in settings.
     *
     * @param session - Session name
     * @param result - Agent run result containing usage data
     */
    private recordTokenUsageIfEnabled;
    /**
     * Check if the runtime is initialized and ready to handle messages.
     *
     * @returns True if initializeInProcess() has been called successfully
     */
    isReady(): boolean;
    /**
     * Abort the currently executing message processing.
     *
     * Cancels the active model call, terminates running tool processes,
     * and returns partial results where possible. Safe to call at any time —
     * returns false if no run is in progress.
     *
     * @returns True if an active run was aborted, false if nothing was running
     */
    abortCurrentRun(): boolean;
    /**
     * Get the current agent runner instance (for inspection/testing).
     *
     * @returns The AgentRunnerService instance, or null if not initialized
     */
    getAgentRunner(): AgentRunnerService | null;
    /**
     * Get the session name this runtime was initialized with.
     *
     * @returns Session name string, or null if not initialized
     */
    getSessionName(): string | null;
    /**
     * Shut down the in-process runtime.
     * Clears the agent runner and resets state.
     */
    shutdown(): void;
    /**
     * Hot-reload the worker process.
     *
     * Kills the existing worker and spawns a fresh one with the stored config.
     * This allows updating agent code without restarting the main backend.
     * Conversation state is reset — use this when deploying new agent logic.
     *
     * @throws Error if not in worker mode or config is missing
     */
    hotReload(): Promise<void>;
    /**
     * Check if the runtime is using a worker process.
     *
     * @returns True if running in worker process mode
     */
    isWorkerMode(): boolean;
    /**
     * Get the worker process PID (for monitoring/debugging).
     *
     * @returns Worker PID, or null if not in worker mode or worker is not running
     */
    getWorkerPid(): number | null;
    /**
     * Initialize a worker child process via fork().
     *
     * Forks the agent-worker.ts entry point and sends the init message
     * with the agent config. Waits for the 'ready' response before resolving.
     *
     * @param config - Full agent config to send to the worker
     * @throws Error if worker fails to initialize within timeout
     */
    private initializeWorker;
    /**
     * Execute a message via the worker process using IPC.
     *
     * Sends a 'run' message to the worker and waits for the 'result' or 'error'
     * response. Streaming events are forwarded to the InProcessLogBuffer in real-time.
     *
     * @param session - Session name
     * @param cleanMessage - Message content (prefix already stripped)
     * @param conversationId - Optional conversation ID
     * @param _metadata - Optional metadata (passed to worker)
     * @returns Agent run result from the worker
     */
    private executeMessageViaWorker;
    /**
     * Handle messages received from the worker process.
     *
     * Routes streaming events to the InProcessLogBuffer and resolves/rejects
     * pending run promises on result/error messages.
     *
     * @param msg - Worker message received via IPC
     */
    private handleWorkerMessage;
    /**
     * Send a typed message to the worker process.
     *
     * @param msg - Parent message to send
     */
    private sendToWorker;
    /**
     * Terminate the worker process gracefully, with a forced kill fallback.
     */
    private terminateWorker;
    /**
     * Get the path to the compiled worker entry file.
     *
     * @returns Absolute path to the agent-worker.js compiled file
     */
    /**
     * @internal Visible for testing — override to provide a custom worker path.
     */
    _workerEntryPath: string | null;
    private getWorkerEntryPath;
    /**
     * Start periodic heartbeat to keep the in-process agent marked as active.
     *
     * Unlike PTY-based agents that get implicit heartbeats from every API call
     * via the middleware, in-process agents only touch the API during message
     * processing. Between messages, this timer ensures the agent stays registered
     * as active in teamAgentStatus.json and the PtyActivityTracker.
     *
     * @param sessionName - Session name to heartbeat for
     */
    private startHeartbeat;
    /**
     * Stop the periodic heartbeat timer.
     */
    private stopHeartbeat;
    /**
     * Load the base system prompt for a given role from file.
     *
     * @param roleName - Role name (maps to config/roles/{roleName}/prompt.md)
     * @returns System prompt content, or a generic fallback if file is missing
     */
    private loadSystemPrompt;
    /**
     * Build an enhanced system prompt that includes the base role prompt
     * plus awareness of available skills and installed addons.
     *
     * Sections appended:
     * 1. Available Skills - summary from AGENT_SKILLS_CATALOG.md
     * 2. Installed Addons - names and versions from each addon's manifest.json
     * 3. Instructions - basic behavioral guidance for the agent
     *
     * All file reads are wrapped in try/catch so missing files are gracefully skipped.
     *
     * @param roleName - Role name for the base prompt lookup
     * @returns Combined system prompt string
     */
    buildEnhancedSystemPrompt(roleName?: string): Promise<string>;
    /**
     * Load and summarize the agent skills catalog file.
     *
     * Reads ~/.crewly/skills/AGENT_SKILLS_CATALOG.md and extracts up to
     * the first 50 lines as a summary. Returns null if the file is missing.
     *
     * @returns Skills summary string, or null if unavailable
     */
    private loadSkillsCatalogSummary;
    /**
     * Scan installed addons and build a summary list.
     *
     * Reads manifest.json from each subdirectory under the addons directory
     * and returns a markdown list of addon names, versions, and descriptions.
     * Returns null if no addons are installed.
     *
     * @returns Addon list string, or null if no addons found
     */
    private loadInstalledAddons;
}
//# sourceMappingURL=crewly-agent-runtime.service.d.ts.map