/** * CAELAgent — Phase 2 interfaces for agent integration with CAEL traces. * * Extends Phase 1 (CAELRecorder/CAELTrace) with agent-specific primitives: * O_t: perception (sensor bridge reads solver fields → SNN input) * C_t: cognition trace (SNN spike train + GOAP goal stack, serialized) * A_t: action (chosen action + alternatives considered) * ΔW_t: world delta (what the action changed in the simulation) * * Usage: * const agent = new CAELAgentLoop(recorder, sensor, cognition, actionMapper); * agent.tick(dt); // perception → cognition → action → physics → record * * Each tick appends 4 entries to the CAEL trace: perception, cognition, action, step. * The hash chain is maintained by the underlying CAELRecorder. */ import type { CAELRecorder } from './CAELRecorder'; import type { SimSolver } from './SimSolver'; /** * A sensor reading from the simulation. The bridge maps solver fields to * agent-consumable arrays (e.g., stress field → SNN input currents). */ export interface SensorReading { /** Which solver field was sampled */ fieldName: string; /** Simulation time at sampling */ simTime: number; /** Sampled values (length = number of sensor neurons) */ values: Float64Array | Float32Array; /** Optional: spatial positions of sensor points */ positions?: Float64Array; } /** * Bridges solver output fields to agent sensory input. * * Implementations define HOW the agent perceives the simulation: * - FieldSensorBridge: samples getField() at fixed spatial points * - StressSensorBridge: maps von Mises stress to SNN input currents * - ThermalSensorBridge: maps temperature field to SNN input */ export interface CAELSensorBridge { /** Unique sensor identifier (for provenance) */ readonly id: string; /** Which solver field names this sensor reads */ readonly fieldNames: readonly string[]; /** * Sample the simulation state and produce sensor readings. * Called once per agent tick, BEFORE cognition. */ sample(solver: SimSolver, simTime: number): SensorReading[]; /** * Encode sensor readings for hashing (deterministic serialization). * Must produce identical output for identical readings. */ encode(readings: SensorReading[]): Record; } /** * A snapshot of the agent's cognitive state at one timestep. */ export interface CognitionSnapshot { /** SNN spike events since last tick (neuronIndex + time) */ spikes: Array<{ neuronIndex: number; timestampMs: number; population?: string; }>; /** Number of SNN neurons that fired */ spikeCount: number; /** GOAP goal stack (top = active goal) */ goalStack: Array<{ id: string; priority: number; status: 'active' | 'satisfied' | 'failed'; }>; /** Active plan (sequence of actions toward current goal) */ activePlan?: { id: string; steps: string[]; currentStep: number; }; /** Optional: membrane voltages for full state reconstruction */ membraneVoltages?: Float32Array; /** Optional: any additional cognitive state (working memory, attention, etc.) */ extra?: Record; } /** * Processes sensor input and produces a cognition snapshot + action selection. * * Implementations define HOW the agent thinks: * - SNNCognitionEngine: snn-webgpu backed LIF cognition (default path) * - GOAPCognition: evaluates goal preconditions, selects next action from plan * - HybridCognition: SNN perception → GOAP planning (the intended architecture) */ export interface CAELCognitionEngine { /** Unique engine identifier (for provenance) */ readonly id: string; /** * Process sensor input and produce cognition snapshot. * Called once per agent tick, AFTER perception, BEFORE action selection. * * @param sensors Sensor readings from the current tick * @param dt Time since last tick (seconds) * @returns Cognition snapshot including spike train and goal stack */ think(sensors: SensorReading[], dt: number): Promise | CognitionSnapshot; /** * Encode cognition snapshot for hashing. * Spike times must be quantized to simulation timestep resolution * for deterministic hashing (see G.CAEL.934). */ encode(snapshot: CognitionSnapshot): Record; } /** * An action the agent can take in the simulation. */ export interface AgentAction { /** Unique action type identifier */ type: string; /** Action parameters (e.g., {nodeIndex: 42, force: [0, 0, 1000]}) */ params: Record; /** Expected utility or confidence (from the cognition engine) */ utility?: number; } /** * The result of action selection: chosen action + alternatives considered. * The alternatives are critical for CAEL — they enable counterfactual analysis * ("what if the agent had chosen action B instead?"). */ export interface ActionDecision { /** The action the agent chose to execute */ chosen: AgentAction; /** Alternative actions that were considered but not chosen */ alternatives: AgentAction[]; /** Why this action was chosen (optional, for human-readable provenance) */ reason?: string; } /** * Selects an action based on cognition state. * Separated from CognitionEngine to allow the same cognition to drive * different action policies (e.g., greedy vs exploratory). */ export interface CAELActionSelector { /** Unique selector identifier */ readonly id: string; /** * Select an action based on the current cognition snapshot. * MUST return both the chosen action AND alternatives for provenance. */ select(cognition: CognitionSnapshot, simTime: number): ActionDecision; /** Encode decision for hashing */ encode(decision: ActionDecision): Record; } /** * Describes what changed in the simulation as a result of an agent action. */ export interface WorldDelta { /** What type of modification was made */ type: 'add_load' | 'remove_load' | 'modify_material' | 'modify_constraint' | 'modify_geometry' | 'custom'; /** Human-readable description */ description: string; /** The modification details (solver-specific) */ details: Record; /** Geometry hash BEFORE the action */ hashBefore: string; /** Geometry hash AFTER the action */ hashAfter: string; } /** * Maps agent actions to simulation state changes. * This is where the agent's decision becomes physics. */ export interface CAELActionMapper { /** Unique mapper identifier */ readonly id: string; /** * Apply an action to the simulation and return what changed. * The mapper modifies the solver state and records the delta. * * @param action The action to apply * @param solver The simulation solver to modify * @param simTime Current simulation time * @returns What changed in the world */ apply(action: AgentAction, solver: SimSolver, simTime: number): WorldDelta; /** Encode delta for hashing */ encode(delta: WorldDelta): Record; } /** * Configuration for the CAEL agent loop. */ export interface CAELAgentConfig { /** Agent identifier (for multi-agent traces) */ agentId: string; /** Sensor bridge (perception) */ sensor: CAELSensorBridge; /** Cognition engine (SNN + GOAP) */ cognition: CAELCognitionEngine; /** Action selector (decision making) */ actionSelector: CAELActionSelector; /** Action mapper (decision → physics) */ actionMapper: CAELActionMapper; /** Whether to record full membrane voltages (expensive but enables dream replay) */ recordFullState?: boolean; } /** * The complete CAEL agent-environment loop. * * Each tick(): * 1. Perception: sensor bridge samples solver fields → SensorReading[] * 2. Cognition: engine processes sensors → CognitionSnapshot (spikes + goals) * 3. Action: selector chooses action → ActionDecision (chosen + alternatives) * 4. Physics: mapper applies action → WorldDelta, then solver.step() * 5. Record: all four components appended to CAEL trace with hash chain * * The resulting trace satisfies: * E_t = H(E_{t-1}, O_t, C_t, A_t, P_t, ΔW_t) */ export declare class CAELAgentLoop { private readonly recorder; private readonly config; private tickCount; constructor(recorder: CAELRecorder, config: CAELAgentConfig); /** * Execute one complete agent-environment loop iteration. * * @param dt Wall-clock delta for this tick (seconds) * @returns The action decision made this tick */ tick(dt: number): Promise; /** Get the current tick count */ getTickCount(): number; /** Get the underlying recorder for trace export */ getRecorder(): CAELRecorder; /** Export the complete CAEL trace as JSONL */ toJSONL(): string; } export interface FieldSensorPoint { /** Normalized position in [0,1] for each axis. */ x: number; y?: number; z?: number; } export interface FieldSensorBridgeConfig { id?: string; fieldName?: string; points: FieldSensorPoint[]; } /** * Samples a solver field (default: von_mises_stress) at fixed spatial points. */ export declare class FieldSensorBridge implements CAELSensorBridge { readonly id: string; readonly fieldNames: readonly string[]; private readonly points; constructor(config: FieldSensorBridgeConfig); sample(solver: SimSolver, simTime: number): SensorReading[]; encode(readings: SensorReading[]): Record; private sampleField; } export interface SimpleActionSelectorConfig { id?: string; defaultActionType?: string; } /** * GOAP utility selector — picks highest utility action and records alternatives. */ export declare class SimpleActionSelector implements CAELActionSelector { readonly id: string; private readonly defaultActionType; constructor(config?: SimpleActionSelectorConfig); select(cognition: CognitionSnapshot, simTime: number): ActionDecision; encode(decision: ActionDecision): Record; private extractUtilities; } export interface StructuralActionMapperConfig { id?: string; /** Geometry arrays used for before/after world-state integrity hashing. */ vertices?: Float32Array | Float64Array; elements?: Uint32Array; /** Preferred field to include in world-state hashing. */ integrityFieldName?: string; } /** * Maps structural actions (e.g. add_load) to solver mutations. */ export declare class StructuralActionMapper implements CAELActionMapper { readonly id: string; private readonly vertices?; private readonly elements?; private readonly integrityFieldName; constructor(config?: StructuralActionMapperConfig); apply(action: AgentAction, solver: SimSolver, _simTime: number): WorldDelta; encode(delta: WorldDelta): Record; private hashWorldState; private hashFieldData; } //# sourceMappingURL=CAELAgent.d.ts.map