<reasoning_content>
Here's a thinking process:

1.  **Understand the User's Request:**
   - **Input:** A monolithic single-file Python implementation containing `Job`, `JobQueue`, `PriorityQueue`, and `process_with_retry()`.
   - **Output:** A refactored package structure with four files: `__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 Info:** The actual implementation code isn't provided. I need to create a reasonable, complete implementation that fits the described structure and requirements, then explain/refactor it as requested. I'll assume standard implementations for these components.

2.  **Analyze the Components:**
   - `Job`: Likely a dataclass or class representing a task (id, payload, status, etc.)
   - `JobQueue`: Basic FIFO queue management (add, remove, process)
   - `PriorityQueue`: Extension or alternative to JobQueue that orders jobs by priority
   - `process_with_retry()`: Function that processes a job with retry logic and exponential backoff
   - I need to design these so they work together logically, even though the original code isn't provided. I'll create a plausible, production-like implementation that matches the requirements.

3.  **Design the Module Structure:**
   - `core.py`: `Job` dataclass, `JobQueue` class (basic operations)
   - `priority.py`: `PriorityQueue` class (inherits from or wraps `JobQueue`, or uses `heapq`)
   - `retry.py`: `process_with_retry()` function (takes a job and a processor function, handles retries/backoff)
   - `__init__.py`: Exports `Job`, `JobQueue`, `PriorityQueue`, `process_with_retry`

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

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

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

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

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

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

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

   *priority.py:*
   ```python
   import heapq
   from typing import Optional
   from .core import Job

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

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

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

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

   *retry.py:*
   ```python
   import time
   from typing import Callable, Any
   from .core import Job

   def process_with_retry(job: Job, processor: Callable[[Job], Any], max_retries: Optional[int] = None) -> Any:
       retries = max_retries if max_retries is not None else job.max_retries
       delay = 1.0  # Base delay

       for attempt in range(1, retries + 2):  # +1 for initial attempt
           try:
               job.attempts = attempt
               job.status = "processing"
               result = processor(job)
               job.status = "completed"
               return result
           except Exception as e:
               job.status = "failed"
               if attempt <= retries:
                   time.sleep(delay * (2 ** (attempt - 1)))  # Exponential backoff
                   job.status = "pending"
               else:
                   raise RuntimeError(f"Job {job.job_id} failed after {retries} retries") from e
   ```

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

5.  **Check Against Requirements:**
   - *Maintain all existing functionality:* Yes, covers Job, JobQueue, PriorityQueue, process_with_retry
   - *Proper imports between modules:* Uses relative imports (`from .core import ...`, `from .priority import ...`, etc.)
   - *Clean public API in __init__.py:* Exports exactly what's needed, uses `__all__`
   - *Each module has a single responsibility:* 
     - `core.py`: Data model and basic FIFO queue
     - `priority.py`: Priority-based queue using heapq
     - `retry.py`: Retry logic with exponential backoff
     - `__init__.py`: Package interface
   - *Structure matches target:* Yes.

6.  **Refine & Self-Correction/Improvement during drafting:**
   - *Issue:* The `process_with_retry` function modifies the job's status and attempts. This is fine, but I should make sure it's clear and type-safe.
   - *Improvement:* Add type hints consistently. Make sure imports are correct. Use relative imports properly.
   - *Consideration:* Should `PriorityQueue` inherit from `JobQueue`? The requirement says "split it into a proper package structure", not necessarily OOP inheritance. Composition or separate implementations are fine. I'll keep them separate but consistent in API (`add`, `pop`, `__len__`).
   - *Consideration:* The retry function uses `time.sleep`. In real systems, this might be async or use a scheduler, but for a refactoring task, synchronous is fine. I'll add a note about async if needed, but keep it simple.
   - *Check imports:* In `priority.py`, `from .core import Job` is correct for a package. Same for `retry.py`.
   - *Check `__init__.py`:* Should export everything needed for public API. Using `__all__` is good practice.

   Let's write out the final code blocks carefully.

   *core.py*:
   ```python
   from dataclasses import dataclass, field
   from typing import Any, List, Optional

   @dataclass
   class Job:
       job_id: str
       payload: Any
       status: str = "pending"
       attempts: int = 0
       max_retries: int = 3
       created_at: float = field(default_factory=lambda: __import__('time').time())

   class JobQueue:
       def __init__(self) -> None:
           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 __len__(self) -> int:
           return len(self._jobs)
   ```
   *Note:* I changed `add`/`pop` to `enqueue`/`dequeue` for clarity, but I'll stick to `add`/`pop` or keep it consistent with typical queue APIs. Actually, `put`/`get` or `enqueue`/`dequeue` is fine. I'll stick to `add`/`pop` to match the prompt's implied naming, or just use standard names. I'll use `add` and `pop` for simplicity.

   Let's adjust `core.py` to be more standard:
   ```python
   from dataclasses import dataclass, field
   from typing import Any, List, Optional
   import time

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

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

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

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

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

   *priority.py*:
   ```python
   import heapq
   from typing import Optional
   from .core import Job

   class PriorityQueue:
       def __init__(self) -> None:
           self._heap: list = []
           self._counter: int = 0

       def add(self, job: Job, priority: int = 0) -> None:
           heapq.heappush(self._heap, (priority, self._counter, job))
           self._counter += 1

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

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

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

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

       for attempt in range(1, retries + 2):
           try:
               job.attempts = attempt
               job.status = "processing"
               result = processor(job)
               job.status = "completed"
               return result
           except Exception as e:
               job.status = "failed"
               if attempt <= retries:
                   time.sleep(delay)
                   delay *= 2  # Exponential backoff
                   job.status = "pending"
               else:
                   raise RuntimeError(f"Job {job.job_id} failed after {retries} retries") from e
   ```

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

7.  **Final Review against Requirements:**
   - ✅ Split into multiple files
   - ✅ Target structure matches exactly
   - ✅ Maintain functionality (Job, JobQueue, PriorityQueue, process_with_retry)
   - ✅ Proper imports (relative imports for package, standard for stdlib)
   - ✅ Clean public API in `__init__.py` with `__all__`
   - ✅ Single responsibility per module
   - I should add brief explanations for each file and how they fit together.
   - I'll also note that the actual implementation details were inferred since the original code wasn't provided, but the structure and patterns are production-ready and directly address the refactoring goal.

   One minor thing: `priority.py` and `retry.py` use `from .core import Job`. This is correct for a package. I'll make sure the imports are explicitly relative to avoid ambiguity.
   I'll also add type hints and docstrings for professionalism.
   The structure is solid. I'll present it clearly.
   I should also mention how to use it, to prove it works.
   All good. Output matches the response. 
   Proceed. 
   Self-Correction/Verification during thought:
   - Check `time` import in `core.py`: `field(default_factory=time.time)` is fine.
   - Check `heapq` usage: correct, min-heap with counter for stability.
   - Check retry logic: exponential backoff implemented correctly (`delay *= 2` after sleep).
   - Check `__init__.py`: clean, uses `__all__`, relative imports.
   - Structure matches target exactly.
   - I'll format the output clearly with file paths and code blocks.
   - I'll add a usage example to demonstrate the public API.
   - Everything looks solid.✅
   Output generation. 
   [Done] 
   *Self-Correction/Note during generation prep*: 
   I should make sure the code blocks are complete and ready to copy-paste. I'll add minimal but necessary docstrings and type hints. I'll also explicitly state that since the original implementation wasn't provided, I've reconstructed a production-grade version that matches the described components and requirements. This manages expectations while delivering exactly what's asked. All good. 
   Proceeds. 
   [Output Generation] -> *See response.* 
   *(Done.)*

</reasoning_content>

<content>
Here's a complete, production-ready refactoring of your monolithic queue into a clean package structure. Since the original implementation wasn't provided, I've reconstructed a standard, type-hinted version that fulfills all your requirements while maintaining clear separation of concerns.

### 📁 Package Structure
```
queue/
├── __init__.py
├── core.py
├── priority.py
└── retry.py
```

---

### `queue/core.py`
**Responsibility:** Data model (`Job`) and basic FIFO queue operations.
```python
from dataclasses import dataclass, field
from typing import Any, List, Optional
import time


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


class JobQueue:
    """Basic FIFO queue for processing jobs."""
    
    def __init__(self) -> None:
        self._queue: List[Job] = []

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

    def pop(self) -> Optional[Job]:
        """Remove and return the next job in FIFO order."""
        return self._queue.pop(0) if self._queue else None

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

---

### `queue/priority.py`
**Responsibility:** Priority-based queue using a min-heap.
```python
import heapq
from typing import Optional
from .core import Job


class PriorityQueue:
    """Priority queue that processes lower priority values first."""
    
    def __init__(self) -> None:
        self._heap: list = []
        self._counter: int = 0  # Ensures stable ordering for equal priorities

    def add(self, job: Job, priority: int = 0) -> None:
        """Add a job with an associated priority."""
        heapq.heappush(self._heap, (priority, self._counter, job))
        self._counter += 1

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

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

---

### `queue/retry.py`
**Responsibility:** Retry logic with exponential backoff.
```python
import time
from typing import Any, Callable, Optional
from .core import Job


def process_with_retry(
    job: Job,
    processor: Callable[[Job], Any],
    base_delay: float = 1.0,
    max_retries: Optional[int] = None
) -> Any:
    """
    Process a job with automatic retries and exponential backoff.
    
    Args:
        job: The job to process.
        processor: Callable that accepts a Job and returns a result.
        base_delay: Initial delay between retries in seconds.
        max_retries: Overrides job.max_retries if provided.
        
    Returns:
        The result of the processor function.
        
    Raises:
        RuntimeError: If all retry attempts are exhausted.
    """
    retries = max_retries if max_retries is not None else job.max_retries
    delay = base_delay

    for attempt in range(1, retries + 2):  # +1 accounts for initial attempt
        try:
            job.attempts = attempt
            job.status = "processing"
            result = processor(job)
            job.status = "completed"
            return result
        except Exception as e:
            job.status = "failed"
            if attempt <= retries:
                time.sleep(delay)
                delay *= 2  # Exponential backoff
                job.status = "pending"
            else:
                raise RuntimeError(
                    f"Job {job.job_id} failed after {retries} retries"
                ) from e
```

---

### `queue/__init__.py`
**Responsibility:** Clean public API surface for the package.
```python
from .core import Job, JobQueue
from .priority import PriorityQueue
from .retry import process_with_retry

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

---

### ✅ Usage Example
```python
from queue import Job, JobQueue, PriorityQueue, process_with_retry

# Basic queue
q = JobQueue()
q.add(Job("job-1", payload={"data": "hello"}))
print(q.pop())  # Job(job_id='job-1', ...)

# Priority queue
pq = PriorityQueue()
pq.add(Job("low", payload="x"), priority=5)
pq.add(Job("high", payload="y"), priority=1)
print(pq.pop().job_id)  # 'high'

# Retry logic
def my_processor(job):
    if job.attempts < 2:
        raise ValueError("Temporary failure")
    return f"Success after {job.attempts} attempts"

job = Job("job-2", payload={}, max_retries=3)
result = process_with_retry(job, my_processor)
print(result)  # Success after 2 attempts
```

### 🔑 Key Refactoring Decisions
1. **Relative Imports**: `from .core import ...` ensures the package works correctly when installed or imported, avoiding circular import pitfalls.
2. **Single Responsibility**: 
   - `core.py` handles data & FIFO semantics
   - `priority.py` handles heap-based ordering
   - `retry.py` handles fault tolerance & timing
   - `__init__.py` acts as the facade
3. **Stable Priority Queue**: Uses a counter tie-breaker so jobs with equal priorities maintain insertion order.
4. **Configurable Backoff**: `base_delay` and `max_retries` are overrideable, making the retry function testable and adaptable.

You can drop this directly into your project as a `queue/` package. Let me know if you need async support, persistence, or worker pool integration!
</content>