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

> Discover Mode D Office Action Response Assistance in handsomestWei/patent-disclosure-skill. This module helps parse patent office actions, embed documents, and find similar cases to speed up response drafting.

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

---

**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`](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/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`](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/tools/oa/config.py))

Mode D's flexibility stems from its configurable embedding architecture. The [`config.py`](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/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`](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/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`](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/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`](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/tools/oa/vault_layout.py))

For human-in-the-loop workflows, Mode D integrates with **Obsidian vaults**. The [`vault_layout.py`](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/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`](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/tools/oa/playbook.py))

The experience manual system provides pre-curated response strategies. The [`playbook.py`](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/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.

```python
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:

```python
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:

- [[`tools/oa/pdf_text.py`](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/tools/oa/pdf_text.py)](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/tools/oa/pdf_text.py) — Document text extraction
- [[`tools/oa/config.py`](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/tools/oa/config.py)](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/tools/oa/config.py) — Embedding configuration and vector-optional flags
- [[`tools/oa/embed.py`](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/tools/oa/embed.py)](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/tools/oa/embed.py) — Provider-agnostic embedding client
- [[`tools/oa/store.py`](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/tools/oa/store.py)](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/tools/oa/store.py) — SQLite vector database operations
- [[`tools/oa/vault_layout.py`](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/tools/oa/vault_layout.py)](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/tools/oa/vault_layout.py) — Obsidian vault structure management
- [[`tools/oa/playbook.py`](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/tools/oa/playbook.py)](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/tools/oa/playbook.py) — Experience manual and response strategies
- [`tests/oa/`](https://github.com/handsomestWei/patent-disclosure-skill/tree/main/tests/oa) — Comprehensive validation suite for Mode D components

## Summary

Mode D Office Action Response Assistance delivers:

- **Document parsing** via [`pdf_text.py`](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/pdf_text.py) for PDF and plain-text office actions
- **Flexible embedding** through configurable providers in [`embed.py`](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/embed.py) and [`config.py`](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/config.py)
- **Dual-mode storage** with [`store.py`](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/store.py) supporting both vector similarity and tag-based search
- **Obsidian integration** via [`vault_layout.py`](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/vault_layout.py) for human-readable case management
- **Strategy guidance** through [`playbook.py`](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/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`](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/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`](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/config.py) module sets `vector_enabled` to false and `recommend_payload` returns `"vector_optional": true`. In this configuration, `search_by_tags()` in [`store.py`](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/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`](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/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`](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/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.