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

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. The infer_patent_type() function examines publication numbers to classify documents:


# 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 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. The decide_mode() function (lines 183‑207) evaluates a plan dictionary to select among three base generation strategies:


# 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 (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:


# 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 demonstrates end‑to‑end routing:


# 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 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

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 (lines 331‑334) and respects the validation rules in structure_lineart_gate.py.


Key Implementation Files

File Purpose Critical Lines
tools/shared/patent_type.py Patent type inference 13‑72
tools/shared/image_gen.py Mode selection and job stamping 183‑241
tools/shared/structure_lineart_gate.py Callout mode validation 127‑129
tools/shared/run_step_to_views.py Orchestration and dispatch 309, 331‑334
SKILL.md User‑facing mode documentation Mode exclusivity section

Summary

  • Type detection in patent_type.py establishes the patent category before any routing occurs.
  • Mode selection in 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.

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 validates callout_mode values, rejecting invalid combinations. The 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 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).

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →