Metadata-Version: 2.4
Name: thesis-review-agent
Version: 0.0.4
Summary: AI-assisted HWPX thesis citation and reference validation
Requires-Python: >=3.12
Description-Content-Type: text/markdown
Requires-Dist: openai-agents>=0.22.3
Requires-Dist: langgraph>=1.2.11
Requires-Dist: python-hwpx>=6.4.0
Requires-Dist: python-dotenv>=1.0.0
Provides-Extra: dev
Requires-Dist: pytest>=9.0.0; extra == "dev"
Requires-Dist: pytest-asyncio>=1.0.0; extra == "dev"

# Thesis Review Agent

HWPX 논문 파일에서 본문 인용과 참고문헌을 찾아, AI 분류와 규칙 기반 검증을 통해
표기 오류 후보를 반환하는 Python 패키지입니다.

## 주요 기능

- HWPX 파일을 문장·문단·서식 정보가 포함된 구조로 변환합니다.
- 본문 인용과 참고문헌 후보를 추출하고 AI로 유형을 분류합니다.
- 인용 규칙(CIT), 참고문헌 일반 규칙(REF), 자료 유형별 규칙(TYP)에 따라 위반 후보를 찾습니다.
- 각 위반에 규칙 ID, 설명, 원문, 위치 정보를 포함합니다.

> 검토 보조 도구입니다. AI 분류와 자동 검증 결과는 최종 학술 판단을 대신하지 않으므로
> 원문과 해당 규정에 대조해 확인하세요.

## 요구 사항

- Python 3.12 이상
- OpenAI API 키
- 입력 문서: HWPX 파일

AI 분류 과정에서 문서의 문장과 참고문헌 정보가 OpenAI API로 전달됩니다. 민감한 자료를
처리하기 전에 조직의 데이터 보호 정책과 API 사용 조건을 확인하세요. API 사용료가 발생할
수 있습니다.

## 설치

```bash
pip install thesis-review-agent
```

## 설정

실행 환경에 API 키를 설정합니다.

```bash
export OPENAI_API_KEY="your-api-key"
```

기본 모델은 현재 `gpt-5.6-luna`입니다. 모델은 패키지 설정에서 관리됩니다.

## 사용법: 이벤트 스트리밍

`ThesisReviewAgent.run()`은 최종 객체 하나를 반환하는 대신, LangGraph 실행 중 발생하는
진행 이벤트를 비동기 스트림으로 제공합니다.

```python
import asyncio
from pathlib import Path

from thesis_review_agent import ThesisReviewAgent


async def main() -> None:
    hwpx_bytes = Path("thesis.hwpx").read_bytes()
    agent = ThesisReviewAgent()

    async for event in agent.run(hwpx_bytes):
        if event["type"] == "custom":
            print(event["data"])  # 노드의 진행 메시지
        elif event["type"] == "updates":
            print(event["data"])  # 각 노드가 갱신한 상태 필드


asyncio.run(main())
```

스트림 이벤트는 `type`, `ns`, `data`를 포함합니다. `custom` 이벤트는 노드 진행 메시지,
`updates` 이벤트는 해당 노드가 반환한 상태 변경분입니다. 따라서 `updates` 하나가 전체
최종 상태인 것은 아닙니다.

## 사용법: 최종 검증 결과 받기

전체 상태가 필요하면 공개된 compiled graph를 직접 호출할 수 있습니다.

```python
import asyncio
from pathlib import Path

from thesis_review_agent import ThesisReviewAgent


async def main() -> None:
    agent = ThesisReviewAgent()
    result = await agent.graph.ainvoke(
        {"hwpx_bytes": Path("thesis.hwpx").read_bytes()}
    )

    for item in result["quotation_violations"]:
        print(item.rule_id, item.quotation, item.message)

    for item in result["reference_violations"]:
        print(item.rule_id, item.text, item.message)


asyncio.run(main())
```

`quotation_violations`와 `reference_violations`는 각각 본문 인용과 참고문헌에서 발견된
위반 후보 목록입니다. 각 항목은 Pydantic 모델이며 JSON 형태가 필요하면
`item.model_dump(mode="json")`을 사용할 수 있습니다.

### 결과 항목

| 필드 | 의미 |
| --- | --- |
| `rule_id` | 위반한 CIT, REF 또는 TYP 규칙 ID |
| `message` | 규칙 위반으로 판단한 이유와 안내 |
| `quotation` | 위반으로 표시된 본문 인용 문자열 (`QuotationViolationModel`) |
| `text` | 위반 인용이 포함된 문장 또는 참고문헌 원문 |
| `section_index`, `paragraph_index`, `run_index`, `content_index`, `sentence_index` | HWPX 문서 내 원문 위치 |

예시 형태:

```json
{
  "rule_id": "CIT-001",
  "message": "괄호 인용의 저자와 연도는 쉼표로 구분해야 합니다.",
  "text": "선행 연구(오동근 2020)는 ...",
  "quotation": "(오동근 2020)",
  "section_index": 0,
  "paragraph_index": 12,
  "run_index": 0,
  "content_index": 0,
  "sentence_index": 1
}
```

## 실행 흐름

```text
HWPX 입력
  → 문서 변환 및 문장 분류
  → 인용 추출·분류
  → 참고문헌 추출·확인·REF/TYP 검증
  → 확인된 참고문헌을 고려한 CIT 검증
  → 결과 스트리밍
```

각 단계와 `State` 필드의 상세 설명은 [`thesis_review_agent/graph/README.md`](thesis_review_agent/graph/README.md)를
참고하세요.

## 현재 한계

- 규칙 검증은 문서에 존재하는 표기와 추출 정보에 기반하며, 모든 학술적 맥락을 자동으로
  확정하지는 못합니다.
- `review_node`는 최종 통합 의견을 생성하는 placeholder입니다. 현재 `final_review`는
  `None`, `review_completed`는 `False`로 반환됩니다.
- 공개 API는 실행 도중 예외를 자체 복구하지 않고 호출자에게 전달합니다.

## 개발용 설치

```bash
git clone <repository-url>
cd thesis_review_agent
python -m pip install -e ".[dev]"
```

## 실제 AI 파이프라인 실행 테스트

저장소의 `tests/test_thesis_review_agent.py`는 목킹 없이 실제 OpenAI Agent를 호출하는
통합 테스트입니다. 저장소 루트의 `.env`에 `OPENAI_API_KEY`를 설정하고, 기본 입력인
`para.hwpx`를 준비한 뒤 다음 명령으로 실행합니다.

```bash
python tests/test_thesis_review_agent.py
```

다른 HWPX 파일을 지정하려면 `THESIS_REVIEW_HWPX` 환경 변수를 설정합니다. 테스트는
노드 진행 메시지와 본문 인용·참고문헌 위반 목록을 출력합니다. 실제 API 요청과 사용료가
발생하므로 일반 단위 테스트와 분리해 `integration` marker를 사용합니다.
