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.pyestablishes the patent category before any routing occurs. - Mode selection in
image_gen.pycombines generation strategy (gen_existing,img2img, default text‑to‑image) with annotation preferences to produce modes A‑E. - Job stamping embeds the final
gen_modeinto 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()andattach_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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →