<reasoning_content>
*   Class: `JobQueue`.
    *   Goal: Add a method `process_job(job_id: str, Processor: Callable) -> bool`.
    *   Behavior:
        1.  Fetch `data` from `add_job(job_id, data)`.
        2.  Call `processor(data)`.
        3.  Retries: Max 4 attempts total (1 initial + 3 retries).
        4.  Retry tracking: Track count per job.
        5.  Exponential Backoff: Delays 1s, 2s, 4s (don't actual sleep, record in data).
        6.  Return: `True` on success, `False` if all 4 fail.
        7.  Constraint: Standard library only. No explanations.

    *   `jobs` dict (likely `job_id -> data`).
    *   `retries` dict (likely `job_id -> int`).

    ```python
    from typing import Callable, Dict, Any

    class JobQueue:
        def __init__(self):
            self.jobs: Dict[str, Dict[str, Any]] = {}
            self.retries: Dict[str, int] = {}

        def add_job(self, job_id: str, data: Dict[str, Any]) -> None:
            self.jobs[job_id] = data
            self.retries[job_id] = 0

        def process_job(self, job_id: str, processor: Callable[[Dict[str, Any]], Any]) -> bool:
            if job_id not in self.jobs:
                return False

            data = self.jobs[job_id]
            max_attempts = 4

            for attempt in range(max_attempts):
                try:
                    processor(data)
                    return True
                except Exception:
                    if attempt < max_attempts - 1:
                        self.retries[job_id] += 1
                        # Delay calculation: 2^(attempt)
                        # Attempt 0 failed -> retry 1 (delay 2^0 = 1)
                        # Attempt 1 failed -> retry 2 (delay 2^1 = 2)
                        # Attempt 2 failed -> retry 3 (delay 2^2 = 4)
                        delay = 2 ** attempt
                        data['last_retry_delay'] = delay
                    else:
                        # Final attempt failed
                        break

            return False
    ```

    *   "Retry count per job": Done.
    *   "Exponential backoff (delays of 1s, 2s, 4s)": Attempt 0 (fail) -> retry 1 (delay 1). Attempt 1 (fail) -> retry 2 (delay 2). Attempt 2 (fail) -> retry 3 (delay 4). Attempt 3 (fail) -> No more retries.
    *   "Do NOT actually sleep — record the delays as data": Done.
    *   "Return True on first successful attempt": Done.
    *   "Return False if all 4 attempts raise": Done.

    Wait, the prompt implies the `JobQueue` class already exists or I should define the base structure if needed. Since the prompt says "Extend the JobQueue class", I should provide the class with `add_job` and the new `process_job`.

    One detail: `data` is the dict passed to `add_job`.
    Let's refine the logic for delays.
    Attempt 1 (Initial): Fail. `retries` becomes 1. `delay` = $2^0 = 1$. Record in `data`.
    Attempt 2 (Retry 1): Fail. `retries` becomes 2. `delay` = $2^1 = 2$. Record in `data`.
    Attempt 3 (Retry 2): Fail. `retries` becomes 3. `delay` = $2^2 = 4$. Record in `data`.
    Attempt 4 (Retry 3): Fail. Loop ends. Return `False`.

    Wait, "Track the retry count per job". Does this mean `self.retries` or inside the `data` dict? The prompt says "Track... per job" then "record the delays as data". I'll use a dictionary to track retry counts to be safe, but usually, "per job" means stateful in the object.

    Let's check the "Delays of 1s, 2s, 4s" requirement.
    Attempt 1 fails -> retry 1 (delay 1)
    Attempt 2 fails -> retry 2 (delay 2)
    Attempt 3 fails -> retry 3 (delay 4)
    Attempt 4 fails -> done.

    ```python
    from typing import Callable, Dict, Any

    class JobQueue:
        def __init__(self):
            self.jobs: Dict[str, Dict[str, Any]] = {}
            self.retry_counts: Dict[str, int] = {}

        def add_job(self, job_id: str, data: Dict[str, Any]) -> None:
            self.jobs[job_id] = data
            self.retry_counts[job_id] = 0

        def process_job(self, job_id: str, processor: Callable[[Dict[str, Any]], Any]) -> bool:
            if job_id not in self.jobs:
                return False

            data = self.jobs[job_id]
            max_attempts = 4

            for attempt_num in range(max_attempts):
                try:
                    processor(data)
                    return True
                except Exception:
                    if attempt_num < max_attempts - 1:
                        self.retry_counts[job_id] += 1
                        delay = 2 ** attempt_num
                        data['retry_delay'] = delay
                    else:
                        break
            return False
    ```

    *Self-correction:* The prompt says "Record the delays as data". Should I record every delay or just the most recent one? Usually, "record the delays" implies capturing the sequence or at least the current one. I'll stick to the current one for simplicity unless specified. Wait, "record the delays" (plural). Maybe a list?
    `data['delays'] = data.get('delays', []) + [delay]`
    However, simplest is usually best. I'll use a list or just overwrite. Let's use a list to be safe for "delays". Actually, the prompt just says "record the delays as data". I'll keep it simple.

    One more check: "Delay calculation: 2^(attempt)".
    Attempt 0 (Initial): Fail -> Delay 1.
    Attempt 1 (Retry 1): Fail -> Delay 2.
    Attempt 2 (Retry 2): Fail -> Delay 4.
    Attempt 3 (Retry 3): Fail -> Done.

    Is "retry count per job" stored in `self.retry_counts`? Yes.

    Wait, should I use `self.retries` as requested? "Track the retry count per job".

    Actually, looking at the prompt again: "Record the delays as data".
    Let's write the final code.
</reasoning_content>

<content>
```python
from typing import Callable, Dict, Any

class JobQueue:
    def __init__(self):
        self.jobs: Dict[str, Dict[str, Any]] = {}
        self.retry_counts: Dict[str, int] = {}

    def add_job(self, job_id: str, data: Dict[str, Any]) -> None:
        self.jobs[job_id] = data
        self.retry_counts[job_id] = 0

    def process_job(self, job_id: str, processor: Callable[[Dict[str, Any]], Any]) -> bool:
        if job_id not in self.jobs:
            return False

        data = self.jobs[job_id]
        max_attempts = 4

        for attempt in range(max_attempts):
            try:
                processor(data)
                return True
            except Exception:
                if attempt < max_attempts - 1:
                    self.retry_counts[job_id] += 1
                    # Exponential backoff: 2^0=1, 2^1=2, 2^2=4
                    delay = 2 ** attempt
                    data['retry_delays'] = data.get('retry_delays', []) + [delay]
                else:
                    break
        
        return False
```
</content>