/** * PainSignalRuntimeFactory — creates PainSignalBridge for a given workspace. * * M8 direction: both openclaw-plugin (after_tool_call hook) and pd-cli * use the same PainSignalBridge to enter the Runtime v2 pain chain. * pd-cli can call this factory without importing openclaw-plugin private code. * * Usage: * import { createPainSignalBridge } from '@principles/core/runtime-v2'; * const bridge = await createPainSignalBridge({ workspaceDir, stateDir, ledgerAdapter }); * await bridge.onPainDetected(data); */ import { PainSignalBridge, type DiagnosticianRunnerLike } from './pain-signal-bridge.js'; import type { RunnerResult } from './runner/runner-result.js'; import type { TrajectoryTurnReader } from './store/context/trajectory-turn-reader.js'; import type { TelemetryEvent } from '../telemetry-event.js'; import type { RuntimeKind } from './runtime-protocol.js'; import type { LedgerAdapter } from './candidate-intake.js'; import type { IntentDocReader } from './intent/intent-doc-reader-port.js'; import type { EffectivePdConfig, InternalAgentName } from './config/pd-config-types.js'; export interface PainSignalRuntimeFactoryOptions { workspaceDir: string; stateDir: string; ledgerAdapter: LedgerAdapter; owner?: string; autoIntakeEnabled?: boolean; /** PRI-306: Effective PD config for config-driven runtime binding. * When provided, takes precedence over WorkflowFunnelLoader. */ effectiveConfig?: EffectivePdConfig; /** PRI-306: Env var accessor for readiness checks. Defaults to process.env. */ getEnvVar?: (name: string) => string | undefined; /** * PRI-468: Optional INTENT.md reader for Stage A intent tension check. * * Provided by the plugin layer (which owns filesystem I/O). When present * AND `intent_engineering` flag is on, Stage A reads INTENT.md and * injects it into the prompt. When absent, intent_engineering degrades * silently to off (telemetry emitted by the runner). * * Core never performs filesystem I/O — it only consumes the port. */ intentDocReader?: IntentDocReader; trajectoryTurnReader?: TrajectoryTurnReader; } /** Total timeout for the 3-stage split pipeline (3 × 20 min = 60 min). * Local GPU inference (e.g. qwen3.6-27b-mtp with 200K context) needs * 10-18 min per stage; 20 min per stage provides headroom. * Shared with pd-cli diagnose command. */ export declare const SPLIT_PIPELINE_TOTAL_TIMEOUT_MS = 3600000; /** Resolved runtime configuration from funnel policy. */ export interface RuntimeConfig { runtimeKind: RuntimeKind; openclawMode?: 'local' | 'gateway'; timeoutMs: number; agentId: string; provider?: string; model?: string; apiKeyEnv?: string; maxRetries?: number; /** Max output tokens (max_tokens) for pi-ai LLM calls. */ maxTokens?: number; /** Optional reasoning level (flows from profile to PiAiRuntimeAdapter; PRI-758). */ reasoning?: 'minimal' | 'low' | 'medium' | 'high' | 'xhigh' | false; /** Custom base URL for OpenAI-compatible providers not in pi-ai's built-in registry. */ baseUrl?: string; /** Optional system prompt (flows from profile to PiAiRuntimeAdapter). */ systemPrompt?: string; /** * PRI-719: the runtimeProfile id this config was resolved FROM (absent on * legacy/CLI-override resolutions). Lets run evidence answer * "which declared profile actually executed" without a second lookup. */ runtimeProfileId?: string; } export interface RuntimeConfigError { ok: false; reason: string; message: string; nextAction: string; } export type RuntimeConfigResult = RuntimeConfig | RuntimeConfigError; export declare function isRuntimeConfigError(result: RuntimeConfigResult): result is RuntimeConfigError; export interface ResolveRuntimeConfigOptions { openclawLocal?: boolean; openclawGateway?: boolean; requestedRuntimeKind?: string; } /** * Resolve runtime configuration from the pd-runtime-v2-diagnosis funnel policy. * Falls back to defaults if no funnel is found. * * @deprecated PRI-393: This function reads .state/workflows.yaml and MUST NOT be * called by production execution paths (probe, run-once, diagnose, pain-retry). * Use resolveRuntimeConfigFromPdConfig() with loadPdConfig() instead. * Retained only for legacy warning / migration detection. * * When `requestedRuntimeKind === 'openclaw-cli'` or policy `runtimeKind === 'openclaw-cli'`: * - CLI flag or file config must provide exactly one mode (local or gateway). * - Both provided: fail loud (conflicting mode). * - Neither provided: fail loud (missing mode). * * When `requestedRuntimeKind === 'config'` (explicit config): * - Config load failure, missing config, or schema error must fail loud. * - Only non-explicit config compatibility paths allow fallback. */ export declare function resolveRuntimeConfig(stateDir: string, explicitConfig?: ResolveRuntimeConfigOptions): RuntimeConfigResult; /** * Validate runtime configuration before adapter creation (D-02). * Throws plain Error (not PDRuntimeError) for config issues (D-06). * Includes migration guidance for D-05 breaking change. */ export declare function validateRuntimeConfig(config: RuntimeConfig): void; /** * PRI-719: taskKind → internalAgents.agents key for the consumer/run-once * peer stages. `rollout_reviewer` maps to the camelCase agent name * `rolloutReviewer` (INTERNAL_AGENT_NAMES); diagnostic stages are NOT here — * they run through the pain-signal bridge, which owns the diagnostician * binding. */ export declare const AGENT_NAME_FOR_TASK_KIND: Readonly>; export interface ResolveRuntimeConfigForAgentOptions { /** Env var accessor for readiness checks. */ readonly getEnvVar: (name: string) => string | undefined; /** * PRI-719: resolve the binding even when the agent is disabled. The * consumer's per-stage scope is governed by the internalization_full_chain * FLAG, not by internalAgents.agents[kind].enabled — the shipped default * config disables philosopher/evaluator/rolloutReviewer yet the full-chain * consumer runs them. `enabled` gates the pain-signal bridge * (diagnostician). Lifts only the gate, through the SAME binding * authority, via a read-only re-enabled view of the config. */ readonly ignoreAgentEnabled?: boolean; } /** * PRI-719: per-agent runtime config resolution. * * Same binding → readiness → adapter-config pipeline as * resolveRuntimeConfigFromPdConfig, parameterized by the internal agent name * so each peer stage resolves ITS OWN * `internalAgents.agents[agent].runtimeProfile` (falling back to * defaultRuntime). Consumer/run-once must resolve per leased/selected task * kind — sharing one agent's binding across the whole chain silently * ignored every other agent's declared profile (EP002-R2 F4). */ export declare function resolveRuntimeConfigForAgent(effectiveConfig: EffectivePdConfig, agentName: InternalAgentName, options: ResolveRuntimeConfigForAgentOptions): RuntimeConfigResult; /** * PRI-306: Resolve runtime configuration from EffectivePdConfig. * * Uses resolveAgentRuntimeBinding() to determine which profile the diagnostician * should use, then checks readiness and produces adapter config. * * This is the new config-driven path that replaces WorkflowFunnelLoader. * When effectiveConfig is provided, this path takes precedence. */ export declare function resolveRuntimeConfigFromPdConfig(effectiveConfig: EffectivePdConfig, getEnvVar: (name: string) => string | undefined): RuntimeConfigResult; export interface DisabledDiagnosticianRunnerOptions { /** Human-readable reason. Defaults to the canonical Owner-disable message. */ readonly failureReason?: string; /** Recovery action surfaced to the Owner / CLI operator. */ readonly nextAction?: string; } export declare const DIAGNOSTICIAN_DISABLED_FAILURE_REASON = "Diagnostician capability is disabled by Owner configuration (internalAgents.agents.diagnostician.enabled=false)"; export declare const DIAGNOSTICIAN_DISABLED_NEXT_ACTION = "Enable internalAgents.agents.diagnostician.enabled in .pd/config.yaml (or Console \u2192 Control Center), then retry."; /** * DisabledDiagnosticianRunner — the single representation of "Diagnostician is * not available" (PRI-638). * * Before PRI-638 this class was selected by the `diagnostician_split_pipeline` * feature flag, which made a rollout flag act as a second kill switch. The * Owner capability authority (`internalAgents.agents.diagnostician.enabled`) is * now the only thing that produces this runner. * * Contract (identical for every entrypoint): * - status: 'failed' * - errorCategory: 'capability_missing' (existing PDErrorCategory — reuse, do * not invent a new enum) * - zero provider/LLM calls: the runner never touches an adapter * - attemptCount stays informational; the task is not marked failed by this * runner, so no LLM retry budget is consumed (see PainSignalBridge) */ export declare class DisabledDiagnosticianRunner implements DiagnosticianRunnerLike { private readonly failureReason; private readonly nextAction; constructor(opts?: DisabledDiagnosticianRunnerOptions); run(taskId: string): Promise; } /** * Map a PainSignalBridge telemetry event onto a storable TelemetryEvent. * Returns null for bridge events that were not emitted in production before * the persistence feature (they keep their pre-main dormant status). */ export declare function mapBridgeTelemetryToStoreEvent(event: { eventType: string; traceId: string; timestamp: string; payload: Record; }): TelemetryEvent | null; /** * PRI-624: dispose + drop every cached bridge for a workspace, releasing * their SQLite handles. Per-cycle workers (Companion workspace worker) call * this after execution; long-lived hosts that reuse the cached bridge do not. */ export declare function disposePainSignalBridgesForWorkspace(workspaceDir: string): Promise; export declare function createPainSignalBridge(opts: PainSignalRuntimeFactoryOptions): Promise; /** * PRI-638: bridge for the "Owner disabled the Diagnostician" state. * * Deliberately built WITHOUT a runtime adapter — there is nothing to call, and * constructing one is what previously forced a hard throw. Everything the * durable Pain path needs (state manager + intake) is still wired, so pains * keep landing and can be diagnosed after the Owner re-enables the agent. */ export declare function invalidatePainSignalBridge(workspaceDir: string, runtimeKind?: string): void; //# sourceMappingURL=pain-signal-runtime-factory.d.ts.map