<reasoning_content>
*   Extend a `JobQueue` class.
    *   Method to add: `process_job(job_id: str, Processor: Callable) -> bool`.
    *   Logic for `process_job`:
        *   Identify data from `add_job(job_id, data)`.
        *   Execute `processor(data)`.
        *   Retry on exception (Max 4 attempts: initial + 3 retries).
        *   Track retry count per job.
        *   Exponential backoff: delays are 1s, 2s, 4s.
        *   *Constraint:* Do NOT `time.sleep()`. Instead, record the delays in the data structure.
        *   Return `True` on success, `False` on total failure.
    *   Constraints: Standard library only, no explanation.

    *   `self.jobs = {}` (mapping `job_id` to `data`).
    *   `self.retries = {}` (mapping `job_id` to `count`).

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

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

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

        def process_job(self, job_id: str, processor: Callable[[Any], None]) -> 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:
                        # Track retries
                        self.retries[job_id] += 1
                        # Exponential backoff: 1, 2, 4
                        delay = 2 ** (self.retries[job_id] - 1)
                        # "Record the delays as data"
                        # Interpretation: store the delay in the data dict or a separate structure?
                        # Requirement says "record the delays as data".
                        # Since data is a dict, I should probably ensure it's a dict and update it.
                        if isinstance(data, dict):
                            data['last_delay'] = delay
                            data['retry_count'] = self.retries[job_id]
                        else:
                             # If data isn't a dict, maybe store elsewhere?
                             # But prompt says "record the delays as data".
                             # I'll assume data is expected to be a dict or handle it safely.
                             pass
                    else:
                        # Last attempt failed
                        return False
            return False
    ```

    *   *Retry Logic:* Initial + 3 retries = 4 attempts.
    *   *Delays:* 1s (after 1st fail), 2s (after 2nd fail), 4s (after 3rd fail).
    *   *No Sleep:* Confirmed.
    *   *Record delays as data:* I'll add keys to the `data` dictionary.

    Wait, the prompt says `processor(data)` where `data` is the dict passed to `add_job`.
    So `data` is a dict.

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

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

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

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

    *   "Make up to 4 total attempts (initial + 3 retries)." -> loop range(4) is correct.
    *   "Track the retry count per job." -> `self.retries`.
    *   "Use exponential backoff (delays of 1s, 2s, 4s)." -> `2 ** (retries - 1)`.
    *   "Record the delays as data." -> Adding to the `data` dict.
    *   "Return True on the first successful attempt. Return False if all 4 attempts raise."

    One detail: If `data` is a dict passed by reference, updating it in `process_job` updates the original.

    Refining `process_job` to match exact signature:
    `process_job(self, job_id: str, processor: Callable) -> bool`

    Let's double check the logic:
    Attempt 0: Try. Fails.
    `retries` becomes 1. `delay` = 2^(1-1) = 1. Data updated.
    Attempt 1: Try. Fails.
    `retries` becomes 2. `delay` = 2^(2-1) = 2. Data updated.
    Attempt 2: Try. Fails.
    `retries` becomes 3. `delay` = 2^(3-1) = 4. Data updated.
    Attempt 3: Try. Fails.
    Returns `False`.

    Wait, `range(4)` goes 0, 1, 2, 3.
    Attempt 0 (Initial)
    Attempt 1 (Retry 1)
    Attempt 2 (Retry 2)
    Attempt 3 (Retry 3)
    Total 4. Correct.

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

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

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

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

    Wait, the prompt says: `processor(data)` where `data` is the dict passed to `add_job`.
    If `data` is not a dict, the prompt implies it *is* a dict because it says "passed to add_job(job_id, data)" and then says "record... as data".

    One final check on "delay" values: 1, 2, 4.
    Retries:
    After 1st fail: `retry_counts` = 1. `2 ** (1-1)` = 1.
    After 2nd fail: `retry_counts` = 2. `2 ** (2-1)` = 2.
    After 3rd fail: `retry_counts` = 3. `2 ** (3-1)` = 4.
    After 4th fail: Loop ends.

    Perfect.

    One detail: "Use only the standard library". Typing is standard library.

    Wait, should I include the `add_job` method or just the extension? The prompt says "Extend the JobQueue class". This usually implies providing the full class or at least the relevant parts. I will provide the class with the new method.

    The signature requested: `process_job(job_id: str, Processor: Callable) -> bool`. Note the capitalized `Processor` in the prompt's text but `processor` (lowercase) in the actual code block provided by user's logic description? I'll use lowercase for the argument name as is standard, but I'll double check the prompt text.
    Actually, it says `processor: Callable`. I'll stick to that.

    One more look: "Record the delays as data". I'll use the key `delay`.

    Wait, is `processor` a Callable that takes `data`?
    Prompt: `Call processor(data)`.
    Yes.
</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]):
        self.jobs[job_id] = data
        self.retry_counts[job_id] = 0

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