What Is Mode D (Office Action Response Assistance) in the Patent Disclosure Skill?

Mode D is the "Office Action Response Assistance" module in the handsomestWei/patent-disclosure-skill repository, providing a complete workflow for parsing patent office action documents, embedding them for semantic search, and retrieving similar historical cases to accelerate response drafting.

Mode D operates as one of four specialized modes (A, B, C, D) within the broader patent disclosure automation framework. It specifically targets the critical patent prosecution phase where applicants must respond to official communications—Office Actions—from patent offices like USPTO or CNIPA. According to the source code, Mode D can function as a lightweight tool without requiring large embedding models, while also supporting full vector-based similarity search when configured.

Core Architecture of Mode D Office Action Response Assistance

The Mode D implementation spans seven interconnected Python modules under tools/oa/, each handling a distinct phase of the office action processing pipeline.

PDF and Text Extraction (tools/oa/pdf_text.py)

The entry point for any office action workflow begins with document ingestion. The extract_pdf_text() function parses PDF files or plain-text notices, extracting clean narrative content suitable for downstream processing.

Key capabilities include:

  • PDF text extraction with structure preservation
  • Plain-text document reading via read_document()
  • Error handling with structured return objects containing ok status and extracted text

The test suite demonstrates extraction of typical CNIPA rejection language, such as "Office Action Art. 22 inventiveness rejection" scenarios.

Embedding Configuration (tools/oa/config.py)

Mode D's flexibility stems from its configurable embedding architecture. The config.py module defines:

  • Provider presets: openai_compatible, minimax, and local fallback options
  • Vector-optional mode: The vector_enabled flag and recommend_payload returning "vector_optional": true
  • Dimensionality control: Configurable embedding dimensions for different deployment scenarios

This design explicitly supports deployment environments where large embedding models are unavailable or undesirable.

Vector Generation (tools/oa/embed.py)

The Embedder class standardizes HTTP calls to embedding providers, ensuring consistent payload structure with required model and dimensions fields. The implementation:

  • Wraps OpenAI-compatible APIs
  • Supports Minimax as an alternative provider
  • Handles authentication via environment variables (e.g., ZHIPUAI_API_KEY)

Vector Storage and Retrieval (tools/oa/store.py)

The persistence layer implements a sqlite-vec extension for local vector operations. Key functions include:

Function Purpose
init_db() Initialize SQLite database with vector extension
upsert_case() Insert or update case with embedding vector
upsert_case_meta() Update case metadata independently
search() Vector similarity search with statute/defect filtering
search_by_tags() Tag-based retrieval when vectors are unavailable

This dual-mode storage system enables Mode D to operate fully whether embeddings are present or not.

Vault Organization (tools/oa/vault_layout.py)

For human-in-the-loop workflows, Mode D integrates with Obsidian vaults. The vault_layout.py module:

  • Defines markdown file structures for OA cases
  • Handles migration from legacy vault formats
  • Generates the "OA看板" canvas for visual case management

Response Strategy Management (tools/oa/playbook.py)

The experience manual system provides pre-curated response strategies. The playbook.py module:

  • Manages installation of strategy templates into Obsidian vaults
  • Links retrieved historical cases to actionable guidance
  • Supplies command-line entry points for manual deployment

Practical Usage: Mode D Office Action Response Assistance Workflow

The following executable example demonstrates the complete Mode D pipeline, from PDF extraction to similarity-based case retrieval.

from pathlib import Path
import sqlite3
import sqlite_vec as sv

from tools.oa.pdf_text import extract_pdf_text
from tools.oa.embed import Embedder
from tools.oa.store import init_db, upsert_case, search


# Step 1: Extract office action text from PDF

pdf_path = Path("samples/office_action.pdf")
extracted = extract_pdf_text(pdf_path)
assert extracted["ok"], f"Extraction failed: {extracted.get('error')}"
office_text = extracted["text"]


# Step 2: Initialize vector-enabled SQLite store

conn = sqlite3.connect("oa_cases.db")
conn.row_factory = sqlite3.Row
conn.enable_load_extension(True)
sv.load(conn)

init_db(conn, dimensions=4, with_vec=True)


# Step 3: Generate embedding vector

embedder = Embedder({
    "provider": "openai_compatible",
    "model": "embedding-3",
    "dimensions": 4,
    "base_url": "https://open.bigmodel.cn/api/paas/v4",
    "api_key_env": "ZHIPUAI_API_KEY",
})

vector = embedder.embed_one(office_text, purpose="document")


# Step 4: Store case with metadata and embedding

case_metadata = {
    "case_id": "oa-2024-001",
    "title": "Office Action – Inventiveness Rejection",
    "patent_type": "invention",
    "statutes": ["专利法第22条第3款"],
    "defect_types": ["inventiveness"],
    "domain": "机械",
    "notice_kind": "office_action",
    "outcome": "pending",
    "strategy": ["amend_claims", "argue_inventive_step"],
    "tags": ["oa/inventiveness", "domain/mechanical"],
    "updated_at": "2024-01-15",
}

upsert_case(
    conn,
    case=case_metadata,
    note_path="cases/oa-2024-001.md",
    body_text=office_text,
    chunks=[("full_text", office_text, vector)]
)


# Step 5: Retrieve similar historical cases

similar_cases = search(
    conn,
    query_vec=vector,
    top_k=5,
    statutes=["专利法第22条第3款"],
    defect_types=["inventiveness"]
)

for case in similar_cases:
    print(f"{case['case_id']}: {case['title']} (score: {case.get('score', 'N/A')})")

Lightweight Mode: Office Action Response Without Embeddings

Mode D's vector_optional design allows operation in resource-constrained environments. When embeddings are unavailable, the same storage and retrieval APIs function via tag-based filtering:

from tools.oa.store import search_by_tags

# Vector-free retrieval using structured metadata

cases = search_by_tags(
    conn,
    top_k=10,
    defect_types=["inventiveness", "enablement"],
    statutes=["专利法第22条第3款", "专利法第26条第3款"],
    domains=["机械", "电子"]
)

This fallback ensures Mode D Office Action Response Assistance remains usable regardless of infrastructure limitations.

Source File Reference

All Mode D functionality is implemented in the following repository locations:

Summary

Mode D Office Action Response Assistance delivers:

  • Document parsing via pdf_text.py for PDF and plain-text office actions
  • Flexible embedding through configurable providers in embed.py and config.py
  • Dual-mode storage with store.py supporting both vector similarity and tag-based search
  • Obsidian integration via vault_layout.py for human-readable case management
  • Strategy guidance through playbook.py experience manual integration
  • Deployment versatility with optional vector operations for lightweight environments

Frequently Asked Questions

What file formats does Mode D support for office action input?

Mode D accepts PDF documents and plain text files. The extract_pdf_text() function in tools/oa/pdf_text.py handles PDF parsing, while read_document() processes text files. Both return standardized dictionaries with extraction status and clean text content suitable for embedding or direct storage.

Can Mode D function without an internet connection or API keys?

Yes, Mode D operates in vector-optional mode when embedding providers are unavailable. The config.py module sets vector_enabled to false and recommend_payload returns "vector_optional": true. In this configuration, search_by_tags() in store.py enables full case retrieval using metadata filters (statutes, defect types, domains, tags) without requiring any embedding vectors or external API calls.

How does Mode D determine which past cases are relevant to a new office action?

Mode D supports two relevance mechanisms. When vectors are enabled, search() performs cosine similarity on embedding vectors with optional filtering by statutes and defect types. Without vectors, search_by_tags() matches on structured metadata fields. Both methods prioritize cases sharing the same legal basis (statutes) and technical problem types (defect_types), as implemented in the store.py query construction logic.

Where are the embedding vectors and case data physically stored?

All data persists in a SQLite database with the sqlite_vec extension loaded, as configured in tools/oa/store.py. The init_db() function creates tables for case metadata, document chunks, and vector embeddings. This single-file database approach ensures portability and eliminates external database dependencies, aligning with Mode D's design for personal or small-team patent prosecution workflows.

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 →