<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 logic 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 Target Structure**:
   - `queue/__init__.py`: Exports `JobQueue`, `Job`
   - `queue/core.py`: `Job` dataclass, basic queue operations
   - `queue/retry.py`: Retry logic with exponential backoff
   - `queue/priority.py`: Priority queue implementation

3.  **Infer/Design the Original Code (Mental Reconstruction)**:
   Since the user didn't provide the actual implementation details, I need to create a reasonable, complete implementation that fits the described structure and requirements. I'll design:
   - `Job`: A dataclass with fields like `id`, `payload`, `status`, `created_at`, `retries`, `max_retries`, `priority`
   - `JobQueue`: Basic FIFO queue with add, get, clear, etc.
   - `PriorityQueue`: Extends or wraps a priority queue (using `heapq` or `queue.PriorityQueue`) with job support
   - `process_with_retry`: A function that processes jobs with retry logic and exponential backoff
   I'll make sure the code is realistic, well-documented, and follows Python best practices.

4.  **Design Each Module**:

   **`queue/core.py`**:
   - Define `Job` as a dataclass
   - Define `JobQueue` with basic FIFO operations
   - Use `typing` for type hints
   - Keep it focused on core data structures and basic queue logic

   **`queue/priority.py`**:
   - Implement `PriorityQueue` that manages jobs with priorities
   - Could use `heapq` or `queue.PriorityQueue`
   - I'll use `heapq` for more control, or stick to `queue.PriorityQueue` for simplicity. Actually, `heapq` is fine, but I'll make it a clean wrapper.
   - Focus on priority-based ordering

   **`queue/retry.py`**:
   - Implement `process_with_retry` function
   - Takes a job and a processor function
   - Implements exponential backoff
   - Handles retries up to `max_retries`
   - Returns result or raises exception after max retries

   **`queue/__init__.py`**:
   - Import and export `Job`, `JobQueue`
   - Maybe also export `PriorityQueue` and `process_with_retry` if needed, but requirement says "Exports: JobQueue, Job"
   - Use `__all__` for clean API

5.  **Draft the Code (Mental Refinement)**:

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

   __all__ = ["Job", "JobQueue", "PriorityQueue", "process_with_retry"]
   ```
   Wait, requirement says "Exports: JobQueue, Job". I'll stick to that, but it's fine to export others internally. I'll make `__all__` explicit.

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

   @dataclass
   class Job:
       id: str
       payload: Any
       status: str = "pending"
       created_at: float = field(default_factory=time.time)
       retries: int = 0
       max_retries: int = 3
       priority: int = 0

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

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

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

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

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

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

       def clear(self) -> None:
           self._queue.clear()
   ```

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

   class PriorityQueue:
       def __init__(self):
           self._heap: List[tuple] = []
           self._counter = 0  # To maintain stability for equal priorities

       def enqueue(self, job: Job) -> None:
           # heapq orders by first element, so we use (-priority, counter, job)
           # negative priority because heapq is min-heap but we want higher priority first
           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)
   ```

   *`queue/retry.py`*:
   ```python
   from __future__ import annotations
   import time
   from typing import Any, Callable, Optional
   from .core import Job

   def process_with_retry(
       job: Job,
       processor: Callable[[Any], Any],
       max_retries: Optional[int] = None,
       base_delay: float = 1.0,
       max_delay: float = 60.0
   ) -> Any:
       retries = max_retries if max_retries is not None else job.max_retries
       last_exception = None

       for attempt in range(retries + 1):
           try:
               result = processor(job.payload)
               job.status = "completed"
               job.retries = attempt
               return result
           except Exception as e:
               last_exception = e
               job.status = "failed"
               job.retries = attempt + 1

               if attempt == retries:
                   break

               # Exponential backoff with jitter
               delay = min(base_delay * (2 ** attempt), max_delay)
               time.sleep(delay)

       job.status = "failed"
       raise last_exception
   ```

6.  **Check Against Requirements**:
   - ✅ Maintain all existing functionality (inferred from description)
   - ✅ Proper imports between modules (relative imports used)
   - ✅ Clean public API in `__init__.py` (exports specified)
   - ✅ Each module has a single responsibility (`core` for data/basic queue, `priority` for priority logic, `retry` for retry/backoff)
   - ✅ Structure matches target

   I should verify imports and relative paths. Using `from .core import Job` etc. is correct for a package.
   I'll add type hints and docstrings for professionalism.
   I'll make sure the code is self-contained and ready to use.

   One minor thing: The requirement says `__init__.py` exports `JobQueue, Job`. I'll explicitly set `__all__ = ["Job", "JobQueue"]` to match exactly, though exporting others is fine. I'll stick to the requirement.

   Let's refine the code slightly for production readiness:
   - Add `__future__` annotations
   - Use `typing` properly
   - Add docstrings
   - Ensure exception handling in retry is robust
   - Make sure `PriorityQueue` and `JobQueue` don't conflict in naming if needed, but they're in different modules so it's fine.

   I'll structure the response clearly with file paths and code blocks.

   Self-Correction/Verification during thought:
   - `PriorityQueue` uses `heapq`. The tuple comparison works fine.
   - `process_with_retry` takes `job` and updates its status/retries. This is good.
   - Imports: `from .core import Job` in `priority.py` and `retry.py` is correct.
   - `__init__.py` should use relative imports.
   - I'll add a brief explanation of how to use it.

   Everything looks solid. I'll generate the response. 
   Structure of response:
   - Brief intro
   - Code for each file
   - Usage example (optional but helpful)
   - Notes on design choices (single responsibility, relative imports, etc.)
   All requirements met. Proceed. 
   Output matches the refined code.✅
   One thing: I should make sure the `Job` dataclass fields are reasonable and match common patterns. `status`, `retries`, `max_retries`, `priority`, `payload`, `id`, `created_at` are standard.
   I'll add `from __future__ import annotations` to all files for forward compatibility.
   I'll ensure type hints are consistent.
   Ready. 
   Output generation. 
   [Done] 
   *Self-Correction/Refinement during generation prep*: 
   Wait, `queue.PriorityQueue` might conflict with `queue.PriorityQueue` from stdlib if someone does `from queue import PriorityQueue`. But since it's a custom package, it's fine. I'll keep it as is.
   I'll make sure the `__init__.py` explicitly exports only what's requested: `Job` and `JobQueue`.
   The code looks production-ready. I'll present it clearly.✅
   Output matches the response. 
   Proceeds. 
   [Output Generation] -> *See response.* 
   *(Note: I'll make sure the code blocks are properly formatted and the explanations are concise.)*
   All good. 
   [Final Check of the Prompt]: "Refactor the monolithic job queue into multiple files." "Target structure: queue/..." "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"
   The prompt doesn't provide the original code, so I'm creating a representative implementation that fits the description. I'll note that I've provided a complete, production-ready implementation that matches the described structure and requirements. I'll make sure the code is cohesive.
   All set.✅
   Output Generation. 
   *(Proceeds)*

</reasoning_content>

<content>
Here's a complete, production-ready refactoring that matches your target structure and requirements. Since the original implementation wasn't provided, I've built a cohesive, type-hinted implementation that demonstrates proper separation of concerns.

### `queue/__init__.py`
```python
"""Job queue package with core, priority, and retry functionality."""

from .core import Job, JobQueue

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

### `queue/core.py`
```python
"""Core data structures and basic FIFO queue operations."""

from __future__ import annotations

import time
from dataclasses import dataclass, field
from typing import Any, List, Optional


@dataclass
class Job:
    """Represents a unit of work to be processed."""
    id: str
    payload: Any
    status: str = "pending"
    created_at: float = field(default_factory=time.time)
    retries: int = 0
    max_retries: int = 3
    priority: int = 0


class JobQueue:
    """Basic FIFO queue for Job objects."""

    def __init__(self) -> None:
        self._queue: List[Job] = []

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

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

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

    def is_empty(self) -> bool:
        """Check if the queue is empty."""
        return len(self._queue) == 0

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

    def clear(self) -> None:
        """Remove all jobs from the queue."""
        self._queue.clear()
```

### `queue/priority.py`
```python
"""Priority-based queue implementation using a min-heap."""

from __future__ import annotations

import heapq
from typing import Optional
from .core import Job


class PriorityQueue:
    """Manages jobs ordered by priority (higher number = higher priority)."""

    def __init__(self) -> None:
        self._heap: list[tuple[int, int, Job]] = []
        self._counter: int = 0  # Ensures FIFO ordering for equal priorities

    def enqueue(self, job: Job) -> None:
        """Add a job to the priority queue."""
        # Negate priority because heapq is a min-heap
        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
        _, _, job = heapq.heappop(self._heap)
        return job

    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 is empty."""
        return len(self._heap) == 0

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

### `queue/retry.py`
```python
"""Retry logic with exponential backoff for job processing."""

from __future__ import annotations

import time
from typing import Any, Callable, Optional
from .core import Job


def process_with_retry(
    job: Job,
    processor: Callable[[Any], Any],
    max_retries: Optional[int] = None,
    base_delay: float = 1.0,
    max_delay: float = 60.0,
) -> Any:
    """
    Execute a processor function for a job with exponential backoff on failure.
    
    Args:
        job: The job to process.
        processor: Callable that accepts job.payload and returns a result.
        max_retries: Maximum number of retry attempts. Defaults to job.max_retries.
        base_delay: Base delay in seconds for backoff calculation.
        max_delay: Maximum delay cap in seconds.
        
    Returns:
        The result of the processor function.
        
    Raises:
        Exception: The last exception raised if max retries are exhausted.
    """
    retries = max_retries if max_retries is not None else job.max_retries
    last_exception: Optional[Exception] = None

    for attempt in range(retries + 1):
        try:
            result = processor(job.payload)
            job.status = "completed"
            job.retries = attempt
            return result
        except Exception as e:
            last_exception = e
            job.status = "failed"
            job.retries = attempt + 1

            if attempt == retries:
                break

            # Exponential backoff with a cap
            delay = min(base_delay * (2 ** attempt), max_delay)
            time.sleep(delay)

    job.status = "failed"
    raise last_exception
```

### Key Design Decisions:
1. **Single Responsibility**: 
   - `core.py` handles data modeling and basic FIFO logic
   - `priority.py` isolates heap-based ordering
   - `retry.py` encapsulates failure handling and backoff math
2. **Relative Imports**: All cross-module imports use `.core` syntax, making the package self-contained and safe to move.
3. **Clean Public API**: `__init__.py` explicitly exports only `Job` and `JobQueue`, hiding implementation details while keeping them accessible via `from queue.priority import PriorityQueue` if needed.
4. **Type Safety**: Full type hints and `from __future__ import annotations` enable forward references and better IDE support.
5. **Stable Priority Ordering**: The counter in `PriorityQueue` ensures FIFO behavior when priorities are equal, preventing heap instability.

### Usage Example:
```python
from queue import Job, JobQueue
from queue.priority import PriorityQueue
from queue.retry import process_with_retry

# Basic queue
q = JobQueue()
q.enqueue(Job(id="1", payload={"task": "email"}, priority=1))
job = q.dequeue()

# Priority queue
pq = PriorityQueue()
pq.enqueue(Job(id="2", payload={"task": "urgent"}, priority=10))

# Retry processing
def my_processor(payload):
    return f"Processed: {payload['task']}"

result = process_with_retry(job, my_processor, max_retries=3)
```

This structure scales cleanly: you can add `monitoring.py`, `storage.py`, or `scheduler.py` later without touching existing modules.
</content>