type ) { return AgentResult::refused( 'unsupported task type' ); } $promoted = 0; foreach ( $context->journal()->recurring_errors( self::NOTE_THRESHOLD, 30 ) as $recurring ) { $agent_id = $recurring['agent_id']; $task_type = (string) ( $recurring['context']['task_type'] ?? '' ); if ( '' === $task_type || self::ID === $agent_id ) { continue; } $action = $recurring['occurrences'] >= self::SKIP_THRESHOLD ? 'skip' : 'note'; $context->memory()->remember( $agent_id, 'lesson:' . $recurring['fingerprint'], array( 'match' => array( 'task_type' => $task_type ), 'action' => $action, 'note' => sprintf( '%s failed %d times: %s', $task_type, $recurring['occurrences'], (string) ( $recurring['context']['message'] ?? $recurring['event'] ) ), 'fingerprint' => $recurring['fingerprint'], 'promoted_at' => time(), ), 'lesson', min( 90, 40 + 10 * $recurring['occurrences'] ), ); ++$promoted; $context->bus()->emit( 'lesson.learned', array( 'agent_id' => $agent_id, 'task_type' => $task_type, 'action' => $action, 'occurrences' => $recurring['occurrences'], ) ); } return AgentResult::ok( array( 'lessons_promoted' => $promoted ) ); } /** * {@inheritDoc} */ public function self_check( AgentContext $context ): HealthReport { global $wpdb; // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $journal_table = $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $wpdb->prefix . 'agyl_agent_journal' ) ); return ( new HealthReport() ) ->add( 'journal_table_exists', ! empty( $journal_table ), '', true ); } }