<reasoning_content>
Here's a thinking process:

1.  **Analyze User Request:**
   - **Input:** A single-file Python implementation of a job queue system containing:
     - `Job` class/dataclass
     - `JobQueue` class
     - `PriorityQueue` class
     - `process_with_retry()` function
   - **Output:** A multi-file package structure:
     ```
     queue/
     ├── __init__.py
     ├── core.py
     ├── retry.py
     └── priority.py
     ```
   - **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
   - **Missing Information:** The actual code for the single-file implementation isn't provided. I need to create a reasonable, complete implementation that fits the described structure and functionality, then split it appropriately. I'll assume standard job queue patterns: `Job` as a dataclass with `id`, `func`, `args`, `kwargs`, `status`, `priority`, etc.; `JobQueue` for basic FIFO/LIFO operations; `PriorityQueue` for priority-based ordering; and `process_with_retry` for retry logic with exponential backoff.

   I'll design the code to be robust, well-documented, and directly address the requirements.

2.  **Deconstruct & Plan Modules:**
   - `core.py`: Should contain `Job` dataclass and basic `JobQueue` functionality (enqueue, dequeue, peek, size, etc.). Single responsibility: Core job data structure and basic queue operations.
   - `priority.py`: Should contain `PriorityQueue` class that extends or wraps basic queue functionality, using Python's `heapq` for priority ordering. Single responsibility: Priority-based job ordering.
   - `retry.py`: Should contain `process_with_retry` function (and maybe a helper decorator or base class, but function is fine) that handles retry logic with exponential backoff, catching exceptions, and updating job status. Single responsibility: Retry execution with backoff.
   - `__init__.py`: Should export the public API: `Job`, `JobQueue`, `PriorityQueue`, `process_with_retry`. Use `__all__` for clarity.

3.  **Draft Code - Module by Module:**

   *core.py*
   ```python
   """Core job data structure and basic queue operations."""
   from dataclasses import dataclass, field
   from typing import Any, Callable, List, Optional
   from collections import deque

   @dataclass
   class Job:
       """Represents a unit of work."""
       func: Callable
       args: tuple = ()
       kwargs: dict = field(default_factory=dict)
       job_id: Optional[str] = None
       status: str = "pending"  # pending, running, completed, failed
       priority: int = 0
       result: Any = None
       error: Optional[Exception] = None

   class JobQueue:
       """Basic FIFO job queue."""
       def __init__(self):
           self._queue: deque[Job] = deque()

       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 next job."""
           return self._queue.popleft() if self._queue else None

       def peek(self) -> Optional[Job]:
           """View the next 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()
   ```

   *priority.py*
   ```python
   """Priority queue implementation for job scheduling."""
   import heapq
   from typing import Optional
   from .core import Job, JobQueue

   class PriorityQueue(JobQueue):
       """Priority-aware job queue using a min-heap."""
       def __init__(self):
           super().__init__()
           self._heap: list = []
           self._counter = 0  # Tie-breaker for jobs with same priority

       def enqueue(self, job: Job) -> None:
           """Add a job to the priority queue."""
           # Use negative priority for max-heap behavior (lower number = higher priority)
           # or keep it simple: lower priority value = higher priority
           # Let's use (priority, counter, job) for heapq
           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]:
           """View the highest priority job without removing it."""
           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)

       def clear(self) -> None:
           self._heap.clear()
           self._counter = 0
   ```

   *retry.py*
   ```python
   """Retry logic with exponential backoff for job execution."""
   import time
   import logging
   from typing import Any, Callable, Optional, Tuple
   from .core import Job

   logger = logging.getLogger(__name__)

   def process_with_retry(
       job: Job,
       max_retries: int = 3,
       base_delay: float = 1.0,
       max_delay: float = 60.0,
       retryable_exceptions: Tuple[Exception, ...] = (Exception,)
   ) -> Any:
       """
       Execute a job with retry logic and exponential backoff.

       Args:
           job: The job to execute.
           max_retries: Maximum number of retry attempts.
           base_delay: Base delay in seconds for backoff calculation.
           max_delay: Maximum delay in seconds between retries.
           retryable_exceptions: Tuple of exception types that trigger a retry.

       Returns:
           The result of the job execution.

       Raises:
           The last exception if all retries are exhausted.
       """
       job.status = "running"
       last_exception = None

       for attempt in range(1, max_retries + 2):  # +1 for initial attempt
           try:
               job.result = job.func(*job.args, **job.kwargs)
               job.status = "completed"
               logger.info(f"Job {job.job_id} completed successfully on attempt {attempt}.")
               return job.result
           except retryable_exceptions as e:
               last_exception = e
               job.error = e
               job.status = "failed"
               logger.warning(f"Job {job.job_id} failed on attempt {attempt}: {e}")

               if attempt <= max_retries:
                   # Exponential backoff: base_delay * 2^(attempt-1), capped at max_delay
                   delay = min(base_delay * (2 ** (attempt - 1)), max_delay)
                   logger.info(f"Retrying job {job.job_id} in {delay:.2f} seconds...")
                   time.sleep(delay)
               else:
                   logger.error(f"Job {job.job_id} exhausted all retries after {max_retries} attempts.")

       # If we get here, all retries failed
       job.status = "failed"
       raise last_exception
   ```

   *__init__.py*
   ```python
   """Job Queue Package - Public API."""
   from .core import Job, JobQueue
   from .priority import PriorityQueue
   from .retry import process_with_retry

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

4.  **Review & Refine (Self-Correction/Verification):**
   - *Requirement 1: Maintain all existing functionality.* The split covers `Job`, `JobQueue`, `PriorityQueue`, and `process_with_retry`. I've implemented them with standard, expected behavior. Since the original code wasn't provided, I'll make sure the implementations are robust and match the described structure. I should note that I'm providing a complete, working implementation that fits the spec.
   - *Requirement 2: Proper imports between modules.* `priority.py` imports from `.core`. `retry.py` imports from `.core`. `__init__.py` imports from all modules. All relative imports are used correctly within the package.
   - *Requirement 3: Clean public API in __init__.py.* `__all__` is defined, exporting only the intended public classes/functions. Internal details (like `logger`, `_counter`, etc.) are not exposed.
   - *Requirement 4: Each module has a single responsibility.*
     - `core.py`: Job dataclass + basic FIFO queue
     - `priority.py`: Priority queue using heapq
     - `retry.py`: Execution & retry logic with backoff
     - `__init__.py`: Package initialization & exports
     This matches the requirement perfectly.
   - *Potential Issues/Improvements:*
     - `PriorityQueue` overrides `enqueue`/`dequeue` but inherits from `JobQueue`. This is fine, but I should make sure the parent class initialization doesn't conflict. `super().__init__()` calls `deque()`, but `PriorityQueue` replaces the internal storage with a heap. That's okay, but maybe I should just inherit from `object` or make `JobQueue` a base class that doesn't enforce FIFO. Actually, it's cleaner to just have `PriorityQueue` be independent or inherit from a common base, but for simplicity and to show proper refactoring, inheriting and overriding is acceptable. I'll adjust `PriorityQueue` to not rely on the parent's internal state to avoid confusion, or just keep it simple. Actually, Python's inheritance for queues is fine as long as methods are overridden. I'll keep it.
     - `process_with_retry` modifies `job.status` and `job.error`. This is typical for job queues. I'll add a `job_id` generation helper or assume it's provided, but it's fine.
     - I should ensure type hints are consistent and the code is production-ready.
     - I'll add docstrings and comments for clarity.
     - I'll verify that `PriorityQueue` correctly handles the heap tie-breaking. `heapq` compares tuples element-wise, so `(priority, counter, job)` works perfectly for stable sorting when priorities are equal.
     - I'll make sure `__init__.py` doesn't create circular imports. It doesn't.
     - I'll structure the output exactly as requested.

   One minor adjustment: `PriorityQueue` inherits from `JobQueue`, but `JobQueue` uses `deque`. `PriorityQueue` overrides `enqueue`, `dequeue`, `peek`, `is_empty`, `size`, `clear`. This means the parent's `deque` is unused. That's fine for demonstration, but I could make `JobQueue` a simple base class or just keep it as is. To be strictly clean, I'll make `JobQueue` a concrete FIFO queue, and `PriorityQueue` will inherit from it but override methods. It's acceptable. Alternatively, I could make `PriorityQueue` standalone. The prompt says "split it into a proper package structure", so inheritance is fine.

   Let's double-check the `process_with_retry` signature. It takes a `Job` and executes it. This is good. I'll add a note that in a real system, you might pass just the callable, but this matches the prompt's structure.

   All looks solid. I'll generate the response with the four files clearly labeled and formatted. I'll also add a brief explanation of the design choices to show how requirements are met.

   Structure check:
   ```
   queue/
   ├── __init__.py
   ├── core.py
   ├── priority.py
   └── retry.py
   ```
   Matches exactly.

   Code quality: Type hints, docstrings, proper error handling, exponential backoff, `__all__` exports, single responsibility principle applied.

   Ready. Output matches response. 
   Self-Correction/Refinement during thought:
   - I should ensure `PriorityQueue` doesn't accidentally use parent's `deque`. I'll explicitly initialize its own state and override methods. It's fine.
   - I'll add a small utility to generate job IDs if not provided, but it's optional. I'll leave it as optional to keep it simple.
   - I'll make sure imports are relative within the package.
   - I'll verify that `process_with_retry` doesn't have side effects that break the queue structure. It just updates the job object, which is standard.

   All good. Proceeding. 
   Output generation. 
   [Output matches the final response]
   Structure:
   - `queue/core.py`
   - `queue/priority.py`
   - `queue/retry.py`
   - `queue/__init__.py`
   Each with clear comments and proper Python practices.✅
   Requirements met: 1, 2, 3, 4.✅
   Ready. 
   *Self-Correction/Note during generation prep*: 
   I should make sure the code is copy-paste ready and follows PEP 8. I'll add `from __future__ import annotations` if needed, but not strictly necessary. I'll stick to standard typing. I'll also ensure `PriorityQueue` correctly handles the inheritance without breaking Liskov substitution principle unnecessarily. Actually, it's better to make `PriorityQueue` independent or inherit from a common base, but for this exercise, overriding is fine. I'll keep it simple.

   Final check of the code:
   `core.py`: `Job` dataclass, `JobQueue` FIFO.
   `priority.py`: `PriorityQueue` using `heapq`, inherits `JobQueue` but overrides storage.
   `retry.py`: `process_with_retry` with exponential backoff.
   `__init__.py`: Clean exports.
   All good.✅
   Output matches response. 
   Proceeds. 
   [Output Generation] -> *See response.* 
   *(Note: I'll make sure the code blocks are clearly separated by filename as requested.)*
   All steps verified. No issues found. Output matches the final refined version. 
   [Done.] 
   *Output Generation* (matches the final response)
   ```python
   # queue/core.py
   ...
   # queue/priority.py
   ...
   # queue/retry.py
   ...
   # queue/__init__.py
   ...
   ```
   Perfect. 
   [Final Check of the Prompt]: "Refactor the monolithic job queue into multiple files." "Take this single-file implementation and split it..." (The user didn't provide the actual code, so I must provide a complete, representative implementation that fits the structure). I'll explicitly state that I'm providing a complete, production-ready implementation that matches the described structure and requirements. This is standard practice when the original code isn't provided but the structure is. I'll make sure it's robust. All good. 
   Proceeds. 
   [Output Generation] -> *Proceeds.*

</reasoning_content>

<content>
Here's a complete, production-ready split that satisfies all your requirements. Since the original single-file code wasn't provided, I've implemented a robust, well-typed version that matches your described structure and responsibilities.

### 📁 `queue/__init__.py`
```python
"""Job Queue Package - Public API"""
from .core import Job, JobQueue
from .priority import PriorityQueue
from .retry import process_with_retry

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

### 📁 `queue/core.py`
```python
"""Core job data structure and basic FIFO queue operations."""
from __future__ import annotations
from dataclasses import dataclass, field
from typing import Any, Callable, Optional
from collections import deque


@dataclass
class Job:
    """Represents a unit of work to be processed."""
    func: Callable
    args: tuple = ()
    kwargs: dict = field(default_factory=dict)
    job_id: Optional[str] = None
    status: str = "pending"  # pending, running, completed, failed
    priority: int = 0
    result: Any = None
    error: Optional[Exception] = None


class JobQueue:
    """Basic FIFO job queue."""
    def __init__(self) -> None:
        self._queue: deque[Job] = deque()

    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 next job."""
        return self._queue.popleft() if self._queue else None

    def peek(self) -> Optional[Job]:
        """View the next 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 queue implementation for job scheduling."""
from __future__ import annotations
import heapq
from typing import Optional
from .core import Job, JobQueue


class PriorityQueue(JobQueue):
    """Priority-aware job queue using a min-heap.
    
    Lower priority values are processed first. Jobs with equal priority
    maintain FIFO order via a monotonic counter.
    """
    def __init__(self) -> None:
        super().__init__()
        self._heap: list[tuple[int, int, Job]] = []
        self._counter: int = 0  # Tie-breaker for stable ordering

    def enqueue(self, job: Job) -> None:
        """Add a job to the priority queue."""
        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]:
        """View the highest priority job without removing it."""
        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)

    def clear(self) -> None:
        self._heap.clear()
        self._counter = 0
```

### 📁 `queue/retry.py`
```python
"""Retry logic with exponential backoff for job execution."""
from __future__ import annotations
import logging
import time
from typing import Any, Tuple
from .core import Job

logger = logging.getLogger(__name__)


def process_with_retry(
    job: Job,
    max_retries: int = 3,
    base_delay: float = 1.0,
    max_delay: float = 60.0,
    retryable_exceptions: Tuple[type[Exception], ...] = (Exception,)
) -> Any:
    """Execute a job with retry logic and exponential backoff.

    Args:
        job: The job to execute.
        max_retries: Maximum number of retry attempts after the first failure.
        base_delay: Base delay in seconds for backoff calculation.
        max_delay: Maximum delay in seconds between retries.
        retryable_exceptions: Tuple of exception types that trigger a retry.

    Returns:
        The result of the job execution.

    Raises:
        The last caught exception if all retries are exhausted.
    """
    job.status = "running"
    last_exception: Exception | None = None

    for attempt in range(1, max_retries + 2):  # +1 accounts for the initial run
        try:
            job.result = job.func(*job.args, **job.kwargs)
            job.status = "completed"
            logger.info("Job %s completed successfully on attempt %d.", job.job_id, attempt)
            return job.result
        except retryable_exceptions as e:
            last_exception = e
            job.error = e
            job.status = "failed"
            logger.warning("Job %s failed on attempt %d: %s", job.job_id, attempt, e)

            if attempt <= max_retries:
                # Exponential backoff: base_delay * 2^(attempt-1), capped at max_delay
                delay = min(base_delay * (2 ** (attempt - 1)), max_delay)
                logger.info("Retrying job %s in %.2f seconds...", job.job_id, delay)
                time.sleep(delay)
            else:
                logger.error("Job %s exhausted all retries after %d attempts.", job.job_id, max_retries)

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

### 🔑 Key Design Decisions
1. **Single Responsibility**: 
   - `core.py` handles data modeling & basic FIFO operations
   - `priority.py` handles heap-based ordering & tie-breaking
   - `retry.py` handles execution, exception handling & backoff math
   - `__init__.py` acts as a clean facade
2. **Proper Imports**: All cross-module imports use relative syntax (`.core`, `.priority`) to avoid circular dependencies and keep the package self-contained.
3. **Public API**: `__all__` explicitly defines the public interface. Internal state (`_heap`, `_counter`, `logger`) remains private.
4. **Type Safety**: Full type hints with `from __future__ import annotations` for forward compatibility and cleaner syntax.
5. **Stable Priority Ordering**: The priority queue uses a monotonic counter as a tie-breaker in the heap tuple `(priority, counter, job)`, ensuring FIFO behavior for equal-priority jobs.

You can now use the package like this:
```python
from queue import Job, JobQueue, PriorityQueue, process_with_retry

job = Job(func=my_function, args=(arg1,), job_id="task-1")
queue = PriorityQueue()
queue.enqueue(job)

result = process_with_retry(queue.dequeue())
```
</content>