<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 a job queue implementation into a proper package structure with multiple files. The target structure is specified, and requirements include maintaining functionality, proper imports, a clean public API in `__init__.py`, and single responsibility per module.

2.  **Analyze the Input/Requirements:**
   - Input: A conceptual single-file structure with `Job`, `JobQueue`, `PriorityQueue`, and `process_with_retry()`.
   - 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
     ```
   - 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

3.  **Identify Missing Information:** The user provided placeholders (`class Job: ...`, etc.) but not the actual implementation. I need to create a reasonable, complete implementation that fits the described structure, ensuring it's functional and follows best practices. I'll assume typical job queue functionality:
   - `Job`: A dataclass with fields like `id`, `payload`, `status`, `created_at`, etc.
   - `JobQueue`: Basic FIFO queue operations (add, get, size, etc.)
   - `PriorityQueue`: Extends or replaces `JobQueue` with priority-based ordering
   - `process_with_retry`: A decorator or function that handles retrying jobs with exponential backoff

   I'll design the code to be realistic, well-documented, and modular.

4.  **Design Each Module:**

   *`queue/core.py`*:
   - Contains `Job` dataclass
   - Contains basic `JobQueue` class with FIFO operations
   - Use `dataclasses`, `typing`, `collections.deque`
   - Keep it simple and focused on core queue operations

   *`queue/priority.py`*:
   - Contains `PriorityQueue` class
   - Uses `heapq` for priority ordering
   - Should probably inherit from or work alongside `JobQueue`, or be a standalone implementation that uses `Job` from `core`
   - I'll make it a standalone implementation that uses `Job` from `core` to avoid circular imports, or use a base class if needed. Actually, it's cleaner to have `PriorityQueue` as a separate implementation that uses `Job` from `core`.

   *`queue/retry.py`*:
   - Contains `process_with_retry` function (likely a decorator)
   - Implements exponential backoff
   - Should accept a job/function and retry logic
   - I'll make it a decorator that wraps a job processing function, or a function that processes a job with retry logic. Given the name `process_with_retry`, it's probably a function that takes a callable/job and handles retries.

   *`queue/__init__.py`*:
   - Imports and exports `Job`, `JobQueue`, `PriorityQueue`
   - Uses `__all__` for clean API
   - Keeps internal modules private (except what's exported)

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"]
   ```

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

   @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

   class JobQueue:
       def __init__(self):
           self._queue = deque()

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

       def dequeue(self) -> Optional[Job]:
           if self._queue:
               job = self._queue.popleft()
               job.status = "running"
               return job
           return None

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

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

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

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

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

   class PriorityQueue:
       def __init__(self):
           self._heap = []
           self._counter = 0  # Tie-breaker for equal priorities

       def enqueue(self, job: Job, priority: int = 0) -> None:
           # heapq is a min-heap, so lower priority value = higher priority
           heapq.heappush(self._heap, (priority, self._counter, job))
           self._counter += 1

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

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

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

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

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

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

   def process_with_retry(
       func: Optional[Callable[..., Any]] = None,
       max_retries: int = 3,
       base_delay: float = 1.0,
       max_delay: float = 60.0,
       backoff_factor: float = 2.0
   ) -> Callable[..., Any]:
       """Decorator that retries a job processing function with exponential backoff."""
       def decorator(func: Callable[..., Any]) -> Callable[..., Any]:
           @functools.wraps(func)
           def wrapper(*args: Any, **kwargs: Any) -> Any:
               last_exception = None
               for attempt in range(max_retries + 1):
                   try:
                       return func(*args, **kwargs)
                   except Exception as e:
                       last_exception = e
                       if attempt == max_retries:
                           raise
                       delay = min(base_delay * (backoff_factor ** attempt), max_delay)
                       time.sleep(delay)
               raise last_exception
           return wrapper

       # Handle both @process_with_retry and @process_with_retry() usage
       if func is not None:
           return decorator(func)
       return decorator
   ```

   Wait, the `process_with_retry` might be intended to work directly with `Job` objects rather than as a decorator. The prompt says `def process_with_retry(): ...`. I'll adjust it to be a function that processes a job, or keep it as a decorator but make it clear. Actually, a common pattern is a function that takes a job and a processor, or a decorator. I'll make it a decorator for simplicity, but I'll also show how it can be used with a job. Alternatively, I'll make it a function that processes a job with retry logic, as that fits the "job queue" context better.

   Let's rethink `process_with_retry` to be a function that takes a callable/job and processes it with retries, or just a decorator. I'll stick with a decorator but make it clear. Actually, the prompt says `def process_with_retry(): ...`, so I'll implement it as a decorator that can also be used as a function if needed, or just a straightforward decorator. I'll make it a decorator for simplicity, but I'll also add a note if needed. Alternatively, I'll make it a function that takes a job and a processing function.

   Let's stick to a decorator pattern but make it flexible. Actually, a common pattern in job queues is:
   ```python
   def process_with_retry(func):
       @functools.wraps(func)
       def wrapper(*args, **kwargs):
           # retry logic
           pass
       return wrapper
   ```
   I'll keep it as a decorator. It's clean and standard.

   Wait, the prompt says `def process_with_retry(): ...` in the original. I'll implement it as a decorator that can be used with or without arguments, which is standard.

   Let's refine `retry.py` to be more job-queue specific:
   ```python
   from __future__ import annotations
   import time
   import functools
   import math
   from typing import Callable, Any, Optional, TypeVar
   from .core import Job

   F = TypeVar('F', bound=Callable[..., Any])

   def process_with_retry(
       func: Optional[F] = None,
       *,
       max_retries: int = 3,
       base_delay: float = 1.0,
       max_delay: float = 60.0,
       backoff_factor: float = 2.0
   ) -> F | Callable[[F], F]:
       def decorator(func: F) -> F:
           @functools.wraps(func)
           def wrapper(*args: Any, **kwargs: Any) -> Any:
               last_exception = None
               for attempt in range(max_retries + 1):
                   try:
                       return func(*args, **kwargs)
                   except Exception as e:
                       last_exception = e
                       if attempt == max_retries:
                           raise
                       delay = min(base_delay * (backoff_factor ** attempt), max_delay)
                       time.sleep(delay)
               raise last_exception
           return wrapper

       if func is not None:
           return decorator(func)
       return decorator
   ```

   Actually, I should consider that `process_with_retry` might be intended to process a `Job` object directly. Let's make it a function that takes a job and a processor, or just keep it as a decorator. I'll stick with the decorator but make it clear. Alternatively, I'll implement it as a function that processes a job with retry logic, which might be more aligned with "job queue" terminology.

   Let's do this: `process_with_retry` as a decorator is fine. I'll add type hints and keep it clean.

   Now, check imports and structure:
   - `queue/__init__.py` imports from `.core`, `.priority`, `.retry`
   - `queue/core.py` has `Job` and `JobQueue`
   - `queue/priority.py` imports `Job` from `.core`
   - `queue/retry.py` imports `Job` from `.core` (though it doesn't strictly need it, I'll keep it for consistency or remove if unused. I'll remove unused imports to be clean)
   - Each module has single responsibility: core (data + basic queue), priority (heap-based queue), retry (backoff logic)

   Let's verify requirements:
   1. Maintain all existing functionality: Yes, covers Job, JobQueue, PriorityQueue, process_with_retry
   2. Proper imports between modules: Yes, relative imports used correctly
   3. Clean public API in __init__.py: Yes, uses `__all__` and explicit imports
   4. Each module has a single responsibility: Yes, clearly separated

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

   One thing: `PriorityQueue` might want to inherit from `JobQueue` or implement the same interface. I'll keep them as separate implementations that share the same interface, which is fine. Alternatively, I could make `JobQueue` an abstract base class, but that might overcomplicate. I'll stick to separate implementations with consistent method signatures.

   Let's draft the final code.

   *Self-Correction/Refinement during thought:*
   - In `core.py`, `JobQueue` uses `deque`. Good.
   - In `priority.py`, `PriorityQueue` uses `heapq`. Good.
   - In `retry.py`, the decorator handles both `@process_with_retry` and `@process_with_retry(max_retries=5)`. Good.
   - I should ensure `__init__.py` doesn't expose internal modules. Using relative imports and `__all__` handles this.
   - I'll add a brief usage example in comments if needed, but the prompt just asks for file contents.
   - I'll make sure type hints are compatible with Python 3.8+ (using `typing.Optional`, `typing.Any`, etc., or `|` for 3.10+). I'll stick to `typing` module for broader compatibility, or use `from __future__ import annotations` which is already there.

   Let's write out the files clearly.

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

   I'll generate the content for each file.
   I'll also add a note about Python version compatibility if needed, but `from __future__ import annotations` handles it.

   Check `retry.py` again: The decorator pattern is fine, but sometimes job queues want a function that processes a job. I'll stick with decorator but make it clear. Actually, I'll implement it as a decorator that can be used with or without arguments, which is standard.

   One improvement: Instead of a decorator, `process_with_retry` could be a function that takes a callable and returns a wrapped callable, or a decorator. I'll keep it as a decorator for simplicity.

   All good. I'll produce the response. 
   I'll make sure the code is complete, well-documented, and matches the requirements exactly.
   I'll also add a small test/example in comments to show how it works, but keep it focused on the file contents.
   Ready.✅
   Output matches the response. 
   Structure check:
   - `queue/__init__.py`: exports Job, JobQueue, PriorityQueue, process_with_retry
   - `queue/core.py`: Job dataclass, JobQueue
   - `queue/priority.py`: PriorityQueue
   - `queue/retry.py`: process_with_retry decorator
   All requirements met. Single responsibility maintained. Proper relative imports. Clean API. Functionality preserved.
   I'll generate it now. 
   One minor thing: `process_with_retry` in the prompt is a function, not necessarily a decorator. I'll make it a function that processes a job with retry logic, or keep it as a decorator. I'll stick with decorator but name it clearly. Actually, I'll make it a decorator but also show how it can be used as a function wrapper. It's fine.
   I'll proceed. 
   Output generation. 
   [Done] 
   *Self-Correction/Verification during generation prep:*
   Wait, `process_with_retry` might be better as a function that takes a job and a processor, like:
   ```python
   def process_with_retry(job: Job, processor: Callable, ...):
       ...
   ```
   But the prompt says `def process_with_retry(): ...` which is vague. I'll stick with the decorator pattern as it's more common in Python for retry logic, but I'll make it flexible. Actually, I'll implement it as a decorator that can also be used as a function if needed, but I'll clarify in comments. Alternatively, I'll make it a straightforward function that wraps a job processing function. I'll keep it as a decorator. It's fine.

   I'll produce the response now. 
   Structure:
   ```python
   # queue/__init__.py
   ...
   # queue/core.py
   ...
   # queue/priority.py
   ...
   # queue/retry.py
   ...
   ```
   All set.✅
   Output matches the final response. 
   [Proceeds]

</reasoning_content>

<content>
Here's the complete refactored package. Each file is designed with single responsibility, proper type hints, and clean relative imports.

### `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 model and basic FIFO queue implementation."""

from __future__ import annotations

import time
from collections import deque
from dataclasses import dataclass, field
from typing import Any, Optional


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


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. Updates status to 'running'."""
        if self._queue:
            job = self._queue.popleft()
            job.status = "running"
            return job
        return None

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

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

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

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

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

from __future__ import annotations

import heapq
from typing import Any, Optional

from .core import Job


class PriorityQueue:
    """Priority queue where lower priority values are processed first."""

    def __init__(self) -> None:
        self._heap: list[tuple[int, int, Job]] = []
        self._counter: int = 0  # Monotonic counter for stable sorting

    def enqueue(self, job: Job, priority: int = 0) -> None:
        """Add a job with a given priority. Lower value = higher priority."""
        heapq.heappush(self._heap, (priority, self._counter, job))
        self._counter += 1

    def dequeue(self) -> Optional[Job]:
        """Remove and return the highest priority job."""
        if self._heap:
            _, _, job = heapq.heappop(self._heap)
            job.status = "running"
            return job
        return None

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

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

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

    def clear(self) -> None:
        """Remove all jobs from the queue."""
        self._heap.clear()
        self._counter = 0
```

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

from __future__ import annotations

import time
import functools
from typing import Any, Callable, Optional, TypeVar

F = TypeVar("F", bound=Callable[..., Any])


def process_with_retry(
    func: Optional[F] = None,
    *,
    max_retries: int = 3,
    base_delay: float = 1.0,
    max_delay: float = 60.0,
    backoff_factor: float = 2.0,
) -> F | Callable[[F], F]:
    """Decorator that retries a function with exponential backoff.
    
    Can be used with or without parentheses:
        @process_with_retry
        @process_with_retry(max_retries=5, base_delay=2.0)
    """
    def decorator(func: F) -> F:
        @functools.wraps(func)
        def wrapper(*args: Any, **kwargs: Any) -> Any:
            last_exception: Optional[Exception] = None
            
            for attempt in range(max_retries + 1):
                try:
                    return func(*args, **kwargs)
                except Exception as e:
                    last_exception = e
                    if attempt == max_retries:
                        raise
                    
                    delay = min(base_delay * (backoff_factor ** attempt), max_delay)
                    time.sleep(delay)
                    
            raise last_exception  # type: ignore[unreachable]
        return wrapper  # type: ignore[return-value]

    if func is not None:
        return decorator(func)
    return decorator  # type: ignore[return-value]
```

### Key Design Decisions:
1. **Single Responsibility**: 
   - `core.py`: Data model + basic FIFO operations
   - `priority.py`: Heap-based ordering (no inheritance, avoids coupling)
   - `retry.py`: Pure retry/backoff logic (framework-agnostic)
   - `__init__.py`: Public API surface only
2. **Import Safety**: All cross-module imports use relative imports (`.core`, `.priority`, etc.) to prevent circular dependencies and keep the package boundary clean.
3. **Type Safety**: Full type hints with `from __future__ import annotations` for forward compatibility and IDE support.
4. **Decorator Flexibility**: `process_with_retry` supports both `@process_with_retry` and `@process_with_retry(max_retries=5)` syntax.
5. **State Management**: Jobs track their own `status` and `retries`, while queues remain stateless regarding business logic.

You can now use it as:
```python
from queue import Job, JobQueue, PriorityQueue, process_with_retry

@process_with_retry(max_retries=3, base_delay=0.5)
def process_job(job: Job) -> None:
    # job processing logic
    pass

q = JobQueue()
q.enqueue(Job(id="1", payload={"task": "data_sync"}))
```
</content>