import type { OrchestratorMetrics, CameraMetrics } from './api-shared.js';
import type { PipelineEngineChoice } from '../types/pipeline.js';
import type { PipelineStepInputOutput } from '../capabilities/pipeline-executor.cap.js';
import type { Zone } from '../capabilities/zones.cap.js';
import type { PipelinePhaseMode } from '../device/device-profile.js';
/**
 * Camera assignment payload sent by the pipeline-orchestrator to a runner
 * via `attachCamera`. Carries everything the runner needs to subscribe to
 * the local stream-broker and dispatch frames to motion / detection caps.
 *
 * Stateless-pipeline model: `engine`, `steps`, and `audio` travel with the
 * payload so the runner holds the full content in RAM for the lifetime of
 * the attach. Re-sent on rebalance, edit, or restart. The fields are
 * optional during the additive migration (Phase 1) — the runner treats
 * absent content as "no inference" until Phase 3 makes them required.
 */
export interface RunnerCameraConfig {
    readonly deviceId: number;
    readonly motionCooldownMs: number;
    readonly motionFps: number;
    readonly detectionFps: number;
    readonly motionStreamId: string;
    readonly detectionStreamId: string;
    /** Motion sources that can activate the pipeline. At least one entry. */
    readonly motionSources: import('../capabilities/pipeline-runner.cap.js').MotionSources;
    readonly pipelineEnabled: boolean;
    /** Engine choice for video steps — Phase 1 optional, runner ignores until Phase 3. */
    readonly engine?: PipelineEngineChoice;
    /** Ordered tree of video steps — Phase 1 optional, runner ignores until Phase 3. */
    readonly steps?: readonly PipelineStepInputOutput[];
    /** Audio classification branch — Phase 1 optional, runner ignores until Phase 3. */
    readonly audio?: {
        readonly engine: PipelineEngineChoice;
        readonly modelId: string;
        readonly enabled: boolean;
    } | null;
    /**
     * Per-camera detection zones (user + onboard) snapshot taken at
     * dispatch time. Empty array → no zone filtering. Forwarded so
     * motion-wasm + pipeline-executor running on the runner can apply
     * include/exclude/monitor logic without an extra hub round-trip;
     * the orchestrator re-attaches the camera whenever the `zones`
     * device-state slice changes so the runner's copy stays in sync.
     */
    readonly zones?: readonly Zone[];
    /**
     * Operator-facing scheduling modes. The runner uses these to gate
     * its substream subscribers + phase machine:
     *
     *   - `'disabled'`   — runner skips the substream subscriber for
     *                      this phase entirely. Bindings stay bound;
     *                      this is the runtime-level off switch.
     *   - `'always-on'`  — phase starts in `'active'` and stays active.
     *   - `'on-motion'`  — phase starts in `'watching'`; transitions to
     *                      `'active'` when a motion source fires; falls
     *                      back after `motionCooldownMs`.
     *
     * `detectionMode` defaults to `'on-motion'` (battery profile keeps
     * this); `audioMode` defaults to `'always-on'` (battery profile
     * lowers to `'disabled'`).
     */
    readonly detectionMode: PipelinePhaseMode;
    readonly audioMode: PipelinePhaseMode;
}
/**
 * Hardware capability flags reported by a runner instance. Consumed by the
 * orchestrator's L3 hardware-aware load balancer to assign cameras to the
 * agent best suited for their detection workload (e.g. high-FPS cameras
 * onto GPU agents, motion-only onto CPU-only agents).
 */
export interface RunnerHardwareCapabilities {
    readonly hasGpu: boolean;
    /** Inference backend identifier (e.g. 'coreml', 'openvino', 'cpu', 'cuda'). */
    readonly inferenceBackend?: string;
    readonly cpuCores?: number;
}
/**
 * Runtime load summary returned by `getLocalLoad`. The orchestrator's L2
 * capacity-based balancer uses this to compute a "least-loaded agent"
 * score when picking a target for new camera assignments.
 */
export interface RunnerLocalLoad {
    readonly nodeId: string;
    readonly attachedCameras: number;
    readonly activeCameras: number;
    readonly avgInferenceFps: number;
    readonly avgInferenceTimeMs: number;
    readonly queueDepthTotal: number;
    readonly hardware: RunnerHardwareCapabilities;
}
/**
 * Aggregate runtime metrics for a runner's whole local pool. Mirrors the
 * legacy `OrchestratorMetrics` shape so dashboards keep working unchanged
 * when they migrate from `pipeline-executor.orchestratorStatus` to the
 * new runner cap.
 */
export interface RunnerLocalMetrics extends OrchestratorMetrics {
    readonly nodeId: string;
}
/**
 * Pipeline Runner provider interface — implemented by `addon-pipeline-runner`.
 *
 * One instance per node (singleton scope). Receives camera assignments from
 * the hub orchestrator, owns the per-camera frame queues + semaphore +
 * motion → detection phase machine, and emits typed events on the bus
 * (`detection.motion-analysis`, `pipeline.inference-result`, `pipeline.trace`).
 *
 * All methods exposed here mirror the cap definition exactly — there are no
 * "local-only" methods, no callbacks, no live object passing. Everything is
 * serializable so the runner is transparently routable across the cluster.
 */
export interface IPipelineRunnerProvider {
    /** Attach a camera to this runner. Subscribes to the local broker. */
    attachCamera(config: RunnerCameraConfig): Promise<{
        success: true;
    }>;
    /** Detach a camera. Unsubscribes from the broker, clears queues. */
    detachCamera(input: {
        deviceId: number;
    }): Promise<{
        success: true;
    }>;
    /**
     * Report an external motion event for a camera. Drives the runner's
     * unified phase machine — every `detected:true` (analyzer or onboard)
     * rearms the cooldown timer; `detected:false` is a no-op. `regions`
     * is populated only by `source: 'analyzer'`.
     */
    reportMotion(input: import('../capabilities/pipeline-runner.cap.js').ReportMotionInput): Promise<{
        success: true;
    }>;
    /** Return load summary used by the orchestrator's load balancer. */
    getLocalLoad(): Promise<RunnerLocalLoad>;
    /** Return aggregate runtime metrics for this runner instance. */
    getLocalMetrics(): Promise<RunnerLocalMetrics>;
    /** Per-camera metrics for cameras attached to this runner. */
    getCameraMetrics(input: {
        deviceId: number;
    }): Promise<CameraMetrics | null>;
    /** All per-camera metrics in one round-trip. */
    getAllCameraMetrics(): ReadonlyArray<{
        deviceId: number;
    } & CameraMetrics>;
    /** List the deviceIds currently attached to this runner. */
    getLocalCameras(): readonly number[];
}
//# sourceMappingURL=pipeline-runner-capability.d.ts.map