<reasoning_content>
*   Goal: Extend a `JobQueue` class with a `process_job` method.
    *   Function Signature: `process_job(job_id: str, processor: Callable) -> bool`.
    *   Logic:
        1.  Retrieve `data` from `add_job(job_id, data)`.
        2.  Execute `processor(data)`.
        3.  Retry on exception (Max 4 total attempts: 1 initial + 3 retries).
        4.  Track retry count per job.
        5.  Exponential backoff (1s, 2s, 4s).
        6.  *Important*: No actual `time.sleep()`. Record delays in the data.
        7.  Return `True` on success, `False` if all 4 attempts fail.
    *   Constraints: Standard library only. No explanations.

    *   I need a base `JobQueue` class first because the prompt implies extension.
    *   The `JobQueue` class needs a storage mechanism for jobs (e.g., a dictionary).
    *   `add_job` needs to store the data.
    *   `process_job` needs to access that data, handle exceptions, manage retries, and update data.

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

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

        def add_job(self, job_id: str, data: Dict[str, Any]):
            self.jobs[job_id] = data

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

            job_data = self.jobs[job_id]
            # Need to track retry count. Maybe initialize it if missing.
            if "retries" not in job_data:
                job_data["retries"] = 0

            max_attempts = 4
            for attempt in range(max_attempts):
                try:
                    processor(job_data)
                    return True
                except Exception:
                    if attempt < max_attempts - 1:
                        # Calculate backoff: 1, 2, 4
                        delay = 2 ** attempt
                        job_data["retries"] = attempt + 1
                        # Record the delay as requested
                        job_data["last_delay"] = delay
                    else:
                        # Exhausted retries
                        return False
            return False
    ```

    *   "Record the delays as data": This implies adding a key to the dictionary.
    *   "Retries": 1s, 2s, 4s for retries 1, 2, and 3.
    *   Delay logic:
        *   Attempt 1 fails -> Retry 1 -> delay 1s.
        *   Attempt 2 fails -> Retry 2 -> delay 2s.
        *   Attempt 3 fails -> Retry 3 -> delay 4s.
        *   Attempt 4 fails -> Done.
    *   Wait, "delays of 1s, 2s, 4s" matches $2^0, 2^1, 2^2$.
    *   The loop `range(4)` gives `attempt` 0, 1, 2, 3.
    *   If `attempt` is 0 (initial) and fails: `delay` = $2^0 = 1$.
    *   If `attempt` is 1 (retry 1) and fails: `delay` = $2^1 = 2$.
    *   If `attempt` is 2 (retry 2) and fails: `delay` = $2^2 = 4$.
    *   If `attempt` is 3 (retry 3) and fails: Loop ends, return False.

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

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

        def add_job(self, job_id: str, data: Dict[str, Any]):
            self.jobs[job_id] = data

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

            job_data = self.jobs[job_id]
            if "retries" not in job_data:
                job_data["retries"] = 0

            for attempt in range(4):
                try:
                    processor(job_data)
                    return True
                except Exception:
                    if attempt < 3:
                        # Exponential backoff: 1, 2, 4
                        delay = 2 ** attempt
                        job_data["retries"] = attempt + 1
                        job_data["last_delay"] = delay
                    else:
                        return False
            return False
    ```

    *   Include `Callable` from `typing`.
    *   Check constraints: Standard library only. Code only.

    *   `process_job` sig: `process_job(job_id: str, processor: Callable) -> bool`.
    *   Wait, the prompt says `processor(data)`. `data` is the dict passed to `add_job`.
    *   Wait, the instructions say "Record the delays as data". This implies updating the dictionary stored in `self.jobs`.

    *Self-Correction on Delays:*
    Attempt 0 (Initial) fails -> Retry 1 (delay 1)
    Attempt 1 (Retry 1) fails -> Retry 2 (delay 2)
    Attempt 2 (Retry 2) fails -> Retry 3 (delay 4)
    Attempt 3 (Retry 3) fails -> Return False.

    The logic `delay = 2 ** attempt` where attempt is 0, 1, 2 fits perfectly.

    Wait, `processor` should take the dict.

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

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

        def add_job(self, job_id: str, data: Dict[str, Any]):
            self.jobs[job_id] = data

        def process_job(self, job_id: str, processor: Callable[[Dict[str, Any]], None]) -> bool:
            if job_id not in self.jobs:
                return False
            
            job_data = self.jobs[job_id]
            if "retries" not in job_data:
                job_data["retries"] = 0
                
            for attempt in range(4):
                try:
                    processor(job_data)
                    return True
                except Exception:
                    if attempt < 3:
                        delay = 2 ** attempt
                        job_data["retries"] = attempt + 1
                        job_data["last_delay"] = delay
                    else:
                        return False
            return False
    ```

    Wait, I should ensure the `JobQueue` class structure is complete based on the prompt's description. The prompt says "Extend the JobQueue class", implying I should provide the class with the existing `add_job` method and the new `process_job` method.

    Let's refine the `processor` type hint to just `Callable` as requested exactly by the prompt (`processor: Callable`).

    Final check:
    - `process_job(job_id: str, processor: Callable) -> bool`? Yes.
    - Call `processor(data)`? Yes.
    - Retry on exception? Yes.
    - Max 4 total attempts? Yes.
    - Track retry count? Yes.
    - Exponential backoff 1, 2, 4? Yes ($2^0, 2^1, 2^2$).
    - No sleep? Yes.
    - Record delays? Yes.
    - Return True/False? Yes.

    Wait, if I call `processor(job_data)`, and the processor modifies `job_data`, the retry logic still works on the updated dict. If it doesn't modify it, it still works.

    One detail: "Make up to 4 total attempts (initial + 3 retries)".
    My loop `range(4)` does exactly 4 iterations.
    Iteration 0: Initial.
    Iteration 1: Retry 1.
    Iteration 2: Retry 2.
    Iteration 3: Retry 3.

    One more thing: "Record the delays as data".
    I'll use `job_data["last_delay"]`.

    Final Python code:

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

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

        def add_job(self, job_id: str, data: Dict[str, Any]):
            self.jobs[job_id] = data

        def process_job(self, job_id: str, processor: Callable) -> bool:
            if job_id not in self.jobs:
                return False
            
            job_data = self.jobs[job_id]
            if "retries" not in job_data:
                job_data["retries"] = 0
            
            for attempt in range(4):
                try:
                    processor(job_data)
                    return True
                except Exception:
                    if attempt < 3:
                        delay = 2 ** attempt
                        job_data["retries"] = attempt + 1
                        job_data["last_delay"] = delay
                    else:
                        return False
            return False
    ```
</reasoning_content>

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

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

    def add_job(self, job_id: str, data: Dict[str, Any]):
        self.jobs[job_id] = data

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

        job_data = self.jobs[job_id]
        if "retries" not in job_data:
            job_data["retries"] = 0

        for attempt in range(4):
            try:
                processor(job_data)
                return True
            except Exception:
                if attempt < 3:
                    # Exponential backoff delays: 2^0=1, 2^1=2, 2^2=4
                    delay = 2 ** attempt
                    job_data["retries"] = attempt + 1
                    job_data["last_delay"] = delay
                else:
                    return False
        return False
```
</content>