# Patent‑Disclosure Multi‑Mode Architecture (A/B/C/D/E): How Tasks Are Routed in the Open‑Source Skill

> Discover how the patent-disclosure skill's multi-mode architecture (A-E) routes patent tasks using runtime dispatch, type detection, and strategy selection. Learn more!

- Repository: [handsomestWei/patent-disclosure-skill](https://github.com/handsomestWei/patent-disclosure-skill)
- Tags: architecture
- Published: 2026-09-02

---

**The patent‑disclosure skill uses a runtime dispatcher to route patent tasks through five logical modes (A‑E) by combining patent‑type detection, generation‑strategy selection, and annotation‑layer configuration.**

The **handsomestWei/patent‑disclosure‑skill** repository implements a sophisticated routing system for automating patent documentation workflows. The multi‑mode architecture separates concerns into detection, selection, and job‑stamping layers, enabling clean pipeline execution for utility models, inventions, and design patents. This article breaks down exactly how the A/B/C/D/E modes are configured and dispatched.

---

## Detecting Patent Task Types

Patent routing begins with **type inference** in [`tools/shared/patent_type.py`](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/tools/shared/patent_type.py). The `infer_patent_type()` function examines publication numbers to classify documents:

```python

# tools/shared/patent_type.py (lines 13, 114‑140)

TYPE_UTILITY_MODEL = "utility_model"

def infer_patent_type(pub_no: str) -> str:
    if re.search(r"实用新型|\butility\s*model\b", t, re.I):
        return TYPE_UTILITY_MODEL
    # ... additional branches for invention / design

```

This canonical classification—`"utility_model"`, `"invention"`, or `"design"`—propagates downstream. All pipelines call this function first, including [`step_to_views.py`](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/step_to_views.py) at line 309, ensuring consistent task identification before mode selection occurs.

---

## How the Mode Selector Maps Requests to A/B/C/D/E

The **mode dispatcher** lives in [`tools/shared/image_gen.py`](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/tools/shared/image_gen.py). The `decide_mode()` function (lines 183‑207) evaluates a plan dictionary to select among three base generation strategies:

```python

# tools/shared/image_gen.py

def decide_mode(plan: dict[str, Any], case_dir: Path) -> dict[str, Any]:
    if plan.get("gen_existing"):           # → Mode A

        mode = GEN_EXISTING
    elif plan.get("img2img"):              # → Mode B or C

        mode = GEN_IMG2IMG
    else:                                   # → Mode D or E

        mode = GEN_TXT2IMG

    return {
        "mode": mode,
        "skip_generation": mode == GEN_EXISTING,
    }

```

**Base modes A‑C** are determined by generation strategy:

- **Mode A (`GEN_EXISTING`)** – Reuses previously generated line‑art without new generation
- **Mode B (`GEN_IMG2IMG`)** – Refines existing sketches through diffusion image‑to‑image transformation
- **Mode C (`GEN_TXT2IMG`)** – Generates line‑art directly from textual prompts

---

## Sub‑Mode Refinement via Callout Configuration

The **annotation layer** further refines routing. In [`structure_lineart_gate.py`](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/structure_lineart_gate.py) (lines 127‑129), the `callout_mode` parameter controls how part identifiers are applied:

| `callout_mode` value | Visual effect |
|---|---|
| `"overlay"` | Transparent numbered anchor overlay |
| `"in_prompt"` | Embedded anchor descriptions in generation prompt |
| `"contour_only"` | Pure contour without annotations |

Combining **generation mode** with **callout mode** produces the complete A‑E taxonomy:

| Logical Mode | Generation Strategy | Callout Mode | Use Case |
|:---|:---|:---|:---|
| **A** | `GEN_EXISTING` | any | Reuse existing line‑art; zero generation cost |
| **B** | `GEN_IMG2IMG` | `"overlay"` | Refine sketch + overlay part numbers |
| **C** | `GEN_IMG2IMG` | `"in_prompt"` | Refine sketch; embed IDs in diffusion prompt |
| **D** | `GEN_TXT2IMG` | `"overlay"` | Generate from text + overlay part numbers |
| **E** | `GEN_TXT2IMG` | `"contour_only"` | Generate pure contour; patent figures without annotations |

---

## Job Stamping: Propagating Mode Decisions

Once selected, modes are **injected into job objects** via `attach_job_mode()` (lines 223‑237). This eliminates downstream conditionals:

```python

# tools/shared/image_gen.py

def attach_job_mode(job: dict[str, Any], decision: dict[str, Any]) -> dict[str, Any]:
    if decision.get("mode") == GEN_EXISTING:
        out["gen_mode"] = GEN_EXISTING
        out["fallback_mode"] = ""
    elif decision.get("mode") == GEN_IMG2IMG:
        out["gen_mode"] = GEN_IMG2IMG
        out["fallback_mode"] = FALLBACK
    else:  # GEN_TXT2IMG

        out["gen_mode"] = GEN_TXT2IMG
        out["fallback_mode"] = ""

```

Every worker—renderers, CAD exporters, PDF builders—reads `job["gen_mode"]` directly. No additional branching logic required.

---

## Runtime Dispatch in Practice

The orchestration layer in [`run_step_to_views.py`](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/run_step_to_views.py) demonstrates end‑to‑end routing:

```python

# Example from tools/shared/run_step_to_views.py

decision = decide_mode(load_plan(case_dir) or {}, case_dir)
jobs = [attach_job_mode(j, decision) for j in jobs]

for job in jobs:
    if job["gen_mode"] == GEN_EXISTING:
        # Skip generation, copy existing files

    elif job["gen_mode"] == GEN_IMG2IMG:
        # Invoke img2img diffusion pipeline

    else:  # GEN_TXT2IMG

        # Invoke text‑to‑image model

```

This pattern appears throughout the codebase. Mode selection happens **once**, then propagates immutably through the job lifecycle.

---

## Complete Routing Flow

| Stage | Source Location | Decision Input | Output Mode |
|:---|:---|:---|:---|
| 1. Detect task | `patent_type.infer_patent_type()` | Publication number pattern | Patent type string |
| 2. Choose generation | `image_gen.decide_mode()` | `plan["gen_existing"]`, `plan["img2img"]` | A, B, or C base |
| 3. Configure annotation | [`structure_lineart_gate.py`](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/structure_lineart_gate.py) | `callout_mode` parameter | D or E variants |
| 4. Stamp job | `image_gen.attach_job_mode()` | Combined mode decision | Job with `gen_mode` key |
| 5. Execute | Downstream workers | `job["gen_mode"]` value | Pipeline‑specific logic |

---

## Working Example: Routing a Utility Model Request

```python
from tools.shared.patent_type import infer_patent_type
from tools.shared.image_gen import decide_mode, attach_job_mode
from pathlib import Path

# Request: utility model with sketch refinement and overlay annotations

pub_no   = "CN2020123456U"  # U suffix → utility model

plan     = {"img2img": True, "callout_mode": "overlay"}
case_dir = Path("/tmp/case123")

# Step 1: Classify patent type

ptype = infer_patent_type(pub_no)        # → "utility_model"

# Step 2: Select generation mode (B: img2img)

decision = decide_mode(plan, case_dir)   # → {"mode": "GEN_IMG2IMG"}

# Step 3: Build and stamp job

job = {"brief": {"patent_type": ptype, "callout_mode": "overlay"}}
job = attach_job_mode(job, decision)     # → job["gen_mode"] == "GEN_IMG2IMG"

# Step 4: Worker executes img2img pipeline with overlay

```

This mirrors the actual implementation in [`run_step_to_views.py`](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/run_step_to_views.py) (lines 331‑334) and respects the validation rules in [`structure_lineart_gate.py`](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/structure_lineart_gate.py).

---

## Key Implementation Files

| File | Purpose | Critical Lines |
|:---|:---|:---|
| [`tools/shared/patent_type.py`](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/tools/shared/patent_type.py) | Patent type inference | 13‑72 |
| [`tools/shared/image_gen.py`](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/tools/shared/image_gen.py) | Mode selection and job stamping | 183‑241 |
| [`tools/shared/structure_lineart_gate.py`](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/tools/shared/structure_lineart_gate.py) | Callout mode validation | 127‑129 |
| [`tools/shared/run_step_to_views.py`](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/tools/shared/run_step_to_views.py) | Orchestration and dispatch | 309, 331‑334 |
| [`SKILL.md`](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/SKILL.md) | User‑facing mode documentation | Mode exclusivity section |

---

## Summary

- **Type detection** in [`patent_type.py`](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/patent_type.py) establishes the patent category before any routing occurs.
- **Mode selection** in [`image_gen.py`](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/image_gen.py) combines generation strategy (`gen_existing`, `img2img`, default text‑to‑image) with annotation preferences to produce modes A‑E.
- **Job stamping** embeds the final `gen_mode` into every job object, creating a single source of truth for downstream components.
- **Zero downstream branching** — workers read `job["gen_mode"]` directly without additional conditionals.
- **Extensible design** — new modes require only extending `decide_mode()` and `attach_job_mode()`.

---

## Frequently Asked Questions

### What triggers Mode A versus Mode B in the patent‑disclosure skill?

Mode A (`GEN_EXISTING`) activates when `plan.get("gen_existing")` returns truthy—typically when a user requests reuse of previously generated line‑art. Mode B (`GEN_IMG2IMG`) triggers when `plan.get("img2img")` is set and `callout_mode` equals `"overlay"`. The distinction is handled entirely within `decide_mode()` in [`tools/shared/image_gen.py`](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/tools/shared/image_gen.py).

### How does the system prevent conflicting mode assignments?

The `decide_mode()` function uses **ordered priority checks**: `gen_existing` takes precedence, then `img2img`, then default `txt2img`. Additionally, [`structure_lineart_gate.py`](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/structure_lineart_gate.py) validates `callout_mode` values, rejecting invalid combinations. The [`SKILL.md`](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/SKILL.md) documentation explicitly defines mode exclusivity rules.

### Can the multi‑mode architecture handle batch jobs with mixed patent types?

Yes. The routing is **per‑job**, not global. Each job carries its own `gen_mode` stamp from `attach_job_mode()`. A batch processing [`run_step_to_views.py`](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/run_step_to_views.py) can interleave utility models (mode B), invention figures (mode D), and contour‑only exports (mode E) in a single execution.

### Why separate `gen_mode` from `callout_mode` in the job structure?

This **separation of concerns** keeps generation strategy (how to produce the image) independent from annotation strategy (how to label it). The architecture allows reuse—Mode B and Mode C share `GEN_IMG2IMG` but differ only in `callout_mode`. Downstream components can ignore annotation details when irrelevant (e.g., CAD exporters) while respecting them when needed (e.g., PDF renderers).