<reasoning_content>
Here's a thinking process:

1.  **Understand the User's Goal:** The user wants to refactor a monolithic Python file (`queue.py`) containing job queue functionality into a properly structured package with multiple files. The target structure is specified, and requirements include maintaining functionality, proper imports, a clean public API, and single responsibility per module.

2.  **Analyze the Current Structure (Implicit):** The user provided a placeholder description:
   ```python
   # queue.py - everything in one file
   class Job: ...
   class JobQueue: ...
   class PriorityQueue: ...
   def process_with_retry(): ...
   ```
   I need to infer reasonable implementations for these components to make the refactoring concrete and functional. I'll design them to be realistic and match the target structure.

   - `Job`: Likely a dataclass representing a job (id, function/callable, args, kwargs, priority, status, retry_count, etc.)
   - `JobQueue`: Basic FIFO queue with add, get, size, is_empty, etc.
   - `PriorityQueue`: Extends or wraps a priority queue (likely using `heapq`), with higher priority processed first.
   - `process_with_retry`: A decorator or function that handles retry logic with exponential backoff for job execution.

3.  **Map to Target Structure:**
   - `queue/__init__.py`: Exports `JobQueue`, `Job`. Might also export `PriorityQueue` and `process_with_retry` if needed, but the requirement says "Exports: JobQueue, Job". I'll stick to that for the public API, but can make others available if needed. I'll follow the exact requirement: `__all__ = ["JobQueue", "Job"]`
   - `queue/core.py`: `Job` dataclass, basic `JobQueue` operations.
   - `queue/retry.py`: `process_with_retry` function/decorator with exponential backoff.
   - `queue/priority.py`: `PriorityQueue` implementation.

4.  **Draft - File by File:**

   **`queue/__init__.py`**
   ```python
   from .core import Job, JobQueue
   from .priority import PriorityQueue
   from .retry import process_with_retry

   __all__ = ["JobQueue", "Job"]
   ```
   Wait, the requirement says "Exports: JobQueue, Job" for `__init__.py`. I'll make sure those are explicitly exported. I can import the others internally or export them too, but I'll stick to the requirement. Actually, it's common to re-export everything, but I'll follow the exact wording: "Exports: JobQueue, Job". I'll add `__all__ = ["JobQueue", "Job"]`.

   **`queue/core.py`**
   Need `Job` and basic `JobQueue`.
   ```python
   from dataclasses import dataclass, field
   from typing import Any, Callable, List, Optional
   import time

   @dataclass
   class Job:
       id: str
       func: Callable
       args: tuple = ()
       kwargs: dict = field(default_factory=dict)
       status: str = "pending"  # pending, running, completed, failed
       priority: int = 0
       created_at: float = field(default_factory=time.time)
       retry_count: int = 0
       max_retries: int = 3

   class JobQueue:
       def __init__(self):
           self._jobs: List[Job] = []

       def enqueue(self, job: Job) -> None:
           self._jobs.append(job)

       def dequeue(self) -> Optional[Job]:
           if not self._jobs:
               return None
           return self._jobs.pop(0)

       def peek(self) -> Optional[Job]:
           return self._jobs[0] if self._jobs else None

       def is_empty(self) -> bool:
           return len(self._jobs) == 0

       def size(self) -> int:
           return len(self._jobs)

       def get_all(self) -> List[Job]:
           return list(self._jobs)
   ```
   This looks solid. Single responsibility: basic data structure and queue operations.

   **`queue/priority.py`**
   Need `PriorityQueue` implementation. Usually uses `heapq` or `queue.PriorityQueue`. I'll use `heapq` for a clean custom implementation, or just wrap a list with heap operations. Let's do a standard heap-based priority queue.
   ```python
   import heapq
   from typing import List, Optional
   from .core import Job

   class PriorityQueue:
       def __init__(self):
           self._heap: List[Job] = []
           self._counter = 0  # Tie-breaker for FIFO within same priority

       def enqueue(self, job: Job) -> None:
           # Lower priority value = higher priority (standard heapq behavior)
           # If we want higher number = higher priority, we can negate it.
           # Let's assume higher number = higher priority for simplicity.
           heapq.heappush(self._heap, (-job.priority, self._counter, job))
           self._counter += 1

       def dequeue(self) -> Optional[Job]:
           if not self._heap:
               return None
           _, _, job = heapq.heappop(self._heap)
           return job

       def peek(self) -> Optional[Job]:
           if not self._heap:
               return None
           return self._heap[0][2]

       def is_empty(self) -> bool:
           return len(self._heap) == 0

       def size(self) -> int:
           return len(self._heap)
   ```
   This is clean and follows single responsibility.

   **`queue/retry.py`**
   Need `process_with_retry` with exponential backoff. This is typically a decorator or a wrapper function. I'll make it a function that can be used as a decorator or a wrapper.
   ```python
   import time
   import random
   from typing import Callable, Any
   from .core import Job

   def process_with_retry(func: Callable, job: Job, base_delay: float = 1.0, max_delay: float = 60.0) -> Any:
       """
       Execute a job function with exponential backoff retry logic.
       """
       last_exception = None
       for attempt in range(job.max_retries + 1):
           try:
               result = func(*job.args, **job.kwargs)
               job.status = "completed"
               return result
           except Exception as e:
               last_exception = e
               job.retry_count = attempt + 1
               job.status = "failed" if attempt == job.max_retries else "pending"

               if attempt < job.max_retries:
                   delay = min(base_delay * (2 ** attempt) + random.uniform(0, 1), max_delay)
                   time.sleep(delay)
               else:
                   job.status = "failed"

       raise last_exception
   ```
   Wait, the requirement says `def process_with_retry(): ...` in the original. It might be a decorator or a standalone function. I'll make it a decorator that works with `Job` objects, or a function that takes a `Job` and executes it with retry logic. Actually, it's cleaner to make it a decorator that wraps a job execution function, or a function that processes a job. Let's stick to a function that takes a `Job` and executes it with retry logic, as that matches the signature in the prompt. Alternatively, it could be a decorator for job functions. I'll make it a function that takes a `Job` and returns the result, handling retries internally. That's practical.

   Let's refine `retry.py` to be more robust and match typical patterns:
   ```python
   import time
   import random
   from typing import Any, Callable
   from .core import Job

   def process_with_retry(job: Job, base_delay: float = 1.0, max_delay: float = 60.0) -> Any:
       """
       Execute a job with exponential backoff retry logic.
       """
       last_exception = None
       for attempt in range(job.max_retries + 1):
           try:
               result = job.func(*job.args, **job.kwargs)
               job.status = "completed"
               return result
           except Exception as e:
               last_exception = e
               job.retry_count = attempt + 1
               job.status = "failed" if attempt == job.max_retries else "pending"

               if attempt < job.max_retries:
                   delay = min(base_delay * (2 ** attempt) + random.uniform(0, 0.5), max_delay)
                   time.sleep(delay)
               else:
                   job.status = "failed"

       raise last_exception
   ```
   This works. I'll adjust the jitter slightly to be standard (full jitter or equal jitter). I'll keep it simple.

5.  **Check Requirements:**
   - Maintain all existing functionality: Yes, `Job`, `JobQueue`, `PriorityQueue`, `process_with_retry` are all present.
   - Proper imports between modules: `core.py` is standalone. `priority.py` imports from `core`. `retry.py` imports from `core`. `__init__.py` imports from all.
   - Clean public API in `__init__.py`: `__all__ = ["JobQueue", "Job"]` as requested.
   - Each module has a single responsibility: `core.py` (data & basic queue), `priority.py` (priority ordering), `retry.py` (execution & retry logic), `__init__.py` (package exports).

   I should also add docstrings and type hints for professionalism. I'll make sure the code is production-ready.

   Let's review `priority.py` again. Using `heapq` is good. I'll add comments explaining the tie-breaker.
   For `retry.py`, I'll make it a decorator-style function or a standalone processor. The prompt says `def process_with_retry(): ...`, so I'll keep it as a function that takes a `Job`. Actually, it might be better as a decorator that wraps a job execution function, but taking a `Job` is more common in queue systems. I'll stick with taking a `Job`.

   Wait, the prompt says:
   ```python
   def process_with_retry(): ...
   ```
   It might be a decorator. I'll make it a decorator that can wrap a job execution function, but to keep it simple and aligned with the `Job` dataclass, I'll make it a function that processes a `Job` with retry logic. I'll add a note that it can be used as a decorator if needed, but I'll implement it as a processor function for clarity.

   Actually, a better approach for `process_with_retry` is to make it a decorator that wraps a callable, but since we have a `Job` object, it's more practical as a function that executes `job.func` with retries. I'll implement it as:
   ```python
   def process_with_retry(job: Job, base_delay: float = 1.0, max_delay: float = 60.0) -> Any:
       ...
   ```
   This matches the signature style.

   Let's structure the files carefully.

   **`queue/__init__.py`**
   ```python
   from .core import Job, JobQueue
   from .priority import PriorityQueue
   from .retry import process_with_retry

   __all__ = ["JobQueue", "Job"]
   ```

   **`queue/core.py`**
   ```python
   from dataclasses import dataclass, field
   from typing import Any, Callable, List, Optional
   import time

   @dataclass
   class Job:
       id: str
       func: Callable
       args: tuple = ()
       kwargs: dict = field(default_factory=dict)
       status: str = "pending"
       priority: int = 0
       created_at: float = field(default_factory=time.time)
       retry_count: int = 0
       max_retries: int = 3

   class JobQueue:
       def __init__(self):
           self._jobs: List[Job] = []

       def enqueue(self, job: Job) -> None:
           self._jobs.append(job)

       def dequeue(self) -> Optional[Job]:
           return self._jobs.pop(0) if self._jobs else None

       def peek(self) -> Optional[Job]:
           return self._jobs[0] if self._jobs else None

       def is_empty(self) -> bool:
           return len(self._jobs) == 0

       def size(self) -> int:
           return len(self._jobs)

       def get_all(self) -> List[Job]:
           return list(self._jobs)
   ```

   **`queue/priority.py`**
   ```python
   import heapq
   from typing import Optional, List
   from .core import Job

   class PriorityQueue:
       def __init__(self):
           self._heap: List[tuple] = []
           self._counter = 0  # Ensures FIFO order for equal priorities

       def enqueue(self, job: Job) -> None:
           # Negate priority so higher numbers are processed first
           heapq.heappush(self._heap, (-job.priority, self._counter, job))
           self._counter += 1

       def dequeue(self) -> Optional[Job]:
           if not self._heap:
               return None
           return heapq.heappop(self._heap)[2]

       def peek(self) -> Optional[Job]:
           return self._heap[0][2] if self._heap else None

       def is_empty(self) -> bool:
           return len(self._heap) == 0

       def size(self) -> int:
           return len(self._heap)
   ```

   **`queue/retry.py`**
   ```python
   import time
   import random
   from typing import Any
   from .core import Job

   def process_with_retry(job: Job, base_delay: float = 1.0, max_delay: float = 60.0) -> Any:
       """
       Execute a job function with exponential backoff and jitter.
       """
       last_exception = None
       for attempt in range(job.max_retries + 1):
           try:
               result = job.func(*job.args, **job.kwargs)
               job.status = "completed"
               return result
           except Exception as e:
               last_exception = e
               job.retry_count = attempt + 1
               job.status = "failed" if attempt == job.max_retries else "pending"

               if attempt < job.max_retries:
                   # Exponential backoff with jitter
                   delay = min(base_delay * (2 ** attempt) + random.uniform(0, 0.5), max_delay)
                   time.sleep(delay)
               else:
                   job.status = "failed"

       raise last_exception
   ```

6.  **Self-Correction/Refinement during thought:**
   - Check imports: `priority.py` imports from `.core`, `retry.py` imports from `.core`, `__init__.py` imports from all. This is correct for a package.
   - Check `__init__.py`: The requirement says "Exports: JobQueue, Job". I'll explicitly set `__all__ = ["JobQueue", "Job"]`. I'll also keep the other imports available for internal use or direct imports if needed, but the public API is restricted as requested.
   - Check functionality: `JobQueue` is basic FIFO. `PriorityQueue` overrides/adds priority logic. `process_with_retry` handles execution and retries. All match the prompt.
   - Type hints: Added throughout.
   - Docstrings: Added for clarity.
   - Edge cases: `heapq` requires comparable items. Using `(-priority, counter, job)` ensures strict ordering. `counter` handles ties. This is standard and robust.
   - `retry.py` raises the last exception after all retries fail. This is standard behavior.
   - I should ensure that the code doesn't have circular imports. `core` has no relative imports. `priority` imports from `core`. `retry` imports from `core`. `__init__` imports from all. No circular dependencies. Good.
   - One minor thing: `queue/__init__.py` might want to re-export `PriorityQueue` and `process_with_retry` for convenience, but the prompt explicitly says "Exports: JobQueue, Job". I'll stick to that, but I'll add a comment that other modules are available for direct import if needed. Actually, I'll just follow the requirement exactly.

   Let's verify the prompt's target structure:
   ```
   queue/
   ├── __init__.py      # Exports: JobQueue, Job
   ├── core.py          # Job dataclass, basic queue operations
   ├── retry.py         # Retry logic with exponential backoff
   └── priority.py      # Priority queue implementation
   ```
   Matches perfectly.

   I'll format the output clearly, providing each file's content in separate code blocks with explanations if needed. I'll also add a brief usage example to demonstrate how they work together, which adds value.

   One thing: `process_with_retry` might be better as a decorator in some contexts, but as a processor function it's fine. I'll keep it as a function that takes a `Job` and executes it. I'll add a note that it can be adapted if needed.

   All looks solid. I'll generate the response. 
   Structure of response:
   - File 1: `queue/__init__.py`
   - File 2: `queue/core.py`
   - File 3: `queue/priority.py`
   - File 4: `queue/retry.py`
   - Brief explanation of design choices (single responsibility, import structure, public API).
   - Ready.✅
   Self-Correction/Verification during drafting:
   - In `priority.py`, `heapq` stores tuples. The comparison will compare `-priority`, then `_counter`, then `job`. Since `job` is a dataclass, comparing it might raise `TypeError` if not comparable. To avoid this, I should ensure the tuple comparison doesn't reach the `job` object. In Python 3, tuples are compared element by element. Since `(-priority, _counter)` are unique enough (counter is always increasing), it won't compare the `job` object. This is safe.
   - In `retry.py`, `random.uniform(0, 0.5)` is fine for jitter. I'll make it `random.uniform(0, base_delay * 0.5)` for better scaling, but it's minor. I'll keep it simple.
   - I'll add `__all__` to `core.py`, `priority.py`, `retry.py` for completeness, though not strictly required.
   - The prompt says "Maintain all existing functionality". Since I don't have the exact original code, I'm providing a robust, standard implementation that matches the described classes/functions. I'll note that the implementations are designed to be drop-in replacements.

   Everything looks good. Proceed. 
   Output matches the response. 
   Structure:
   ```
   queue/
   ├── __init__.py
   ├── core.py
   ├── priority.py
   └── retry.py
   ```
   Content provided for each. Clear, professional, meets all constraints.✅
   One minor adjustment: I'll make `process_with_retry` a decorator-style function that can also be used as a wrapper, but I'll stick to the simpler processor function as it's more standard for job queues. Actually, I'll keep it as `def process_with_retry(job: Job, ...) -> Any:` as drafted. It's clean.
   I'll also add type hints and docstrings to all files.
   Done. 
   Output generation. 
   [Self-Correction/Refinement during thought]
   Wait, `heapq` comparison: `(-priority, self._counter, job)`. If two items have same priority and counter is unique, it never compares `job`. So it's safe. But to be strictly safe and avoid any Python version quirks, I'll keep it as is. It's standard.
   Also, in `__init__.py`, I'll explicitly export only what's requested, but I'll import the others so they can be accessed via `queue.priority.PriorityQueue()` if needed, or just leave them out of `__all__`. The prompt says "Exports: JobQueue, Job", so I'll set `__all__ = ["JobQueue", "Job"]`.
   All good. 
   Proceeds. 
   Output matches the final response. 
   [Final Check of the Prompt]
   "Refactor the monolithic job queue into multiple files."
   "Current structure (single file): ... class Job: ... class JobQueue: ... class PriorityQueue: ... def process_with_retry(): ..."
   "Target structure: ..."
   "Requirements: 1. Maintain all existing functionality 2. Proper imports between modules 3. Clean public API in __init__.py 4. Each module has a single responsibility"
   "Provide the content of each file."
   All constraints met. I will generate the response now. 
   Output Generation. 
   *(Self-Correction/Note during generation prep)*: I should make sure the code is complete and runnable. I'll add necessary imports and type hints. I'll also ensure that `priority.py` and `retry.py` work correctly with the `Job` dataclass. The design is solid. I'll present it clearly. 
   Ready. 
   [Output Generation] -> *Proceeds*

</reasoning_content>

<content>
Here's the refactored package structure with clean separation of concerns, proper typing, and a focused public API.

### `queue/__init__.py`
```python
"""Job Queue Package

Public API exports only Job and JobQueue. 
Other components are available for direct import if needed.
"""
from .core import Job, JobQueue
from .priority import PriorityQueue
from .retry import process_with_retry

__all__ = ["JobQueue", "Job"]
```

### `queue/core.py`
```python
"""Core data structures and basic FIFO queue operations."""
from dataclasses import dataclass, field
from typing import Any, Callable, List, Optional
import time


@dataclass
class Job:
    """Represents a unit of work to be processed."""
    id: str
    func: Callable
    args: tuple = ()
    kwargs: dict = field(default_factory=dict)
    status: str = "pending"  # pending, running, completed, failed
    priority: int = 0
    created_at: float = field(default_factory=time.time)
    retry_count: int = 0
    max_retries: int = 3


class JobQueue:
    """Basic FIFO queue for job management."""
    
    def __init__(self) -> None:
        self._jobs: List[Job] = []

    def enqueue(self, job: Job) -> None:
        """Add a job to the end of the queue."""
        self._jobs.append(job)

    def dequeue(self) -> Optional[Job]:
        """Remove and return the first job in the queue."""
        return self._jobs.pop(0) if self._jobs else None

    def peek(self) -> Optional[Job]:
        """Return the first job without removing it."""
        return self._jobs[0] if self._jobs else None

    def is_empty(self) -> bool:
        """Check if the queue contains no jobs."""
        return len(self._jobs) == 0

    def size(self) -> int:
        """Return the number of jobs in the queue."""
        return len(self._jobs)

    def get_all(self) -> List[Job]:
        """Return a copy of all jobs in the queue."""
        return list(self._jobs)
```

### `queue/priority.py`
```python
"""Priority queue implementation using a min-heap."""
import heapq
from typing import Optional, List
from .core import Job


class PriorityQueue:
    """Priority-aware queue where higher priority values are processed first."""
    
    def __init__(self) -> None:
        self._heap: List[tuple] = []
        self._counter = 0  # Ensures stable FIFO ordering for equal priorities

    def enqueue(self, job: Job) -> None:
        """Add a job to the priority queue."""
        # Negate priority so higher numbers surface first
        heapq.heappush(self._heap, (-job.priority, self._counter, job))
        self._counter += 1

    def dequeue(self) -> Optional[Job]:
        """Remove and return the highest priority job."""
        if not self._heap:
            return None
        return heapq.heappop(self._heap)[2]

    def peek(self) -> Optional[Job]:
        """Return the highest priority job without removing it."""
        return self._heap[0][2] if self._heap else None

    def is_empty(self) -> bool:
        """Check if the queue contains no jobs."""
        return len(self._heap) == 0

    def size(self) -> int:
        """Return the number of jobs in the queue."""
        return len(self._heap)
```

### `queue/retry.py`
```python
"""Retry logic with exponential backoff and jitter."""
import time
import random
from typing import Any
from .core import Job


def process_with_retry(
    job: Job, 
    base_delay: float = 1.0, 
    max_delay: float = 60.0
) -> Any:
    """
    Execute a job function with exponential backoff retry logic.
    
    Args:
        job: The job instance to process.
        base_delay: Initial delay in seconds between retries.
        max_delay: Maximum delay cap in seconds.
        
    Returns:
        The result of the job's execution function.
        
    Raises:
        The last caught exception if all retries are exhausted.
    """
    last_exception = None
    
    for attempt in range(job.max_retries + 1):
        try:
            result = job.func(*job.args, **job.kwargs)
            job.status = "completed"
            return result
        except Exception as e:
            last_exception = e
            job.retry_count = attempt + 1
            job.status = "failed" if attempt == job.max_retries else "pending"

            if attempt < job.max_retries:
                # Exponential backoff with jitter to prevent thundering herd
                delay = min(
                    base_delay * (2 ** attempt) + random.uniform(0, 0.5), 
                    max_delay
                )
                time.sleep(delay)
            else:
                job.status = "failed"

    raise last_exception
```

### Key Design Decisions:
1. **Single Responsibility**: 
   - `core.py` handles data modeling and basic FIFO operations
   - `priority.py` isolates heap-based ordering logic
   - `retry.py` encapsulates execution, delay calculation, and state mutation
   - `__init__.py` strictly controls the public surface area
2. **Import Safety**: Relative imports prevent circular dependencies. `core.py` is fully self-contained, making it safe to import anywhere without side effects.
3. **Heap Stability**: `PriorityQueue` uses a monotonic counter as a tie-breaker to guarantee FIFO behavior when priorities are equal, avoiding `TypeError` from comparing `Job` dataclasses.
4. **State Management**: Job status is mutated in-place by `process_with_retry`, allowing downstream consumers to inspect retry counts and final states without returning complex tuples.
5. **Public API**: `__all__` restricts `from queue import *` to only `Job` and `JobQueue`, while still allowing explicit imports like `from queue.priority import PriorityQueue` when needed.
</content>