Metadata-Version: 2.4
Name: expense-agent
Version: 0.1.0
Summary: Local reimbursement invoice and payment proof matching agent
License: MIT
Keywords: expense,feishu,invoice,ocr,reimbursement
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Requires-Python: >=3.10
Requires-Dist: paddleocr>=3.5.0
Requires-Dist: paddlepaddle>=3.3.1
Requires-Dist: pypdf>=4.0.0
Requires-Dist: tomli>=2.0.0; python_version < '3.11'
Provides-Extra: test
Requires-Dist: pytest>=8.0.0; extra == 'test'
Description-Content-Type: text/markdown

# Expense Agent

本地运行的报销凭证匹配与自动命名 Agent。当前版本使用规则引擎，不依赖大模型。

支持 macOS、Linux 和 Windows。Python 要求 3.10+，依赖通过 `uv` 管理。

## 运行

```bash
uv run python -m expense_agent.app.main --input ./input --output ./output
```

也可以在已安装依赖的环境中运行：

```bash
python -m expense_agent.app.main --input ./input --output ./output
```

## 输入

支持 `pdf`、`jpg`、`jpeg`、`png`。

- PDF：使用 `pypdf` 提取文本。
- 图片：默认使用 `PaddleOCREngine` 调用 PaddleOCR。若 PaddleOCR 未安装或初始化失败，会在结果中输出明确错误信息。
- 开发和测试时仍可使用同名 `.txt` 旁路作为 mock OCR 文本。例如 `payment.png` 对应 `payment.txt`。

## OCR

真实图片 OCR 需要安装 PaddleOCR：

```bash
uv add paddleocr paddlepaddle
```

OCR 层通过 `OCREngine` 抽象接入，当前默认实现是 `PaddleOCREngine`，后续可增加 RapidOCR 或视觉模型 fallback。

支付凭证优先支持微信支付截图，会从 OCR 文本抽取金额、收款方、支付时间、交易单号和支付渠道。金额抽取按以下标签优先级匹配：`实付金额`、`支付金额`、`付款金额`、`本次支付`、`金额`。

## 输出

输出目录包含：

- `renamed/`：按建议文件名生成的副本，不覆盖原始文件。
- `result.json`：结构化识别和匹配结果。
- `summary.txt`：人工可读摘要和异常说明。

异常、风险和审核提示只写入 `result.json` 与 `summary.txt`，不会塞进文件名。

## 飞书多维表格 Job

手动处理一批“待处理”记录：

```bash
uv run python -m expense_agent.app.feishu_job --once
```

定时串行处理：

```bash
uv run python -m expense_agent.app.feishu_job --schedule
```

运行前需要配置：

```bash
export FEISHU_APP_ID=
export FEISHU_APP_SECRET=
export FEISHU_APP_TOKEN=
export FEISHU_TABLE_ID=
export FIELD_STATUS=处理状态
export FIELD_INVOICE=发票原件
export FIELD_PAYMENT=支付凭证
export FIELD_CONSUMPTION_DETAIL=消费清单
export FIELD_OUTPUT_INVOICE=重命名后的发票附件
export FIELD_OUTPUT_PAYMENT=重命名后的支付凭证
export FIELD_OUTPUT_CONSUMPTION_DETAIL=重命名后的消费清单
export FIELD_INVOICE_AMOUNT=发票识别金额
export FIELD_PAYMENT_AMOUNT=支付凭证识别金额
export FIELD_INVOICE_DATE=开票日期
export FIELD_SELLER=销售方
export FIELD_BUYER=购买方
export FIELD_PAYMENT_TIME=支付时间
export FIELD_EXPENSE_TYPE=费用类型
export FIELD_MATCH_RESULT=匹配结果
export FIELD_RISK=风险等级
export FIELD_SUMMARY=处理说明
export FIELD_PROCESSED_AT=处理时间
export FIELD_ERROR_MESSAGE=错误信息
# 可选：默认走系统临时目录下的 expense-agent-workspace
# export WORKSPACE_DIR=/tmp/expense-agent-workspace
```

可以参考 `.env.example` 准备本地环境变量；真实 `.env` 不应提交到 Git。`feishu_job` 启动时会自动读取当前工作目录下的 `.env`（如果存在），不再依赖 shell 的 `source` 行为。也可以手动导出环境变量后再运行。

跨平台启动方式：

```bash
# macOS / Linux：可直接依赖自动加载
uv run python -m expense_agent.app.feishu_job --once

# 或显式 source（旧用法仍可用）
set -a && source .env && set +a
uv run python -m expense_agent.app.feishu_job --once
```

```powershell
# Windows PowerShell：直接运行，自动加载当前目录的 .env
uv run python -m expense_agent.app.feishu_job --once
```

```cmd
:: Windows cmd.exe
uv run python -m expense_agent.app.feishu_job --once
```

`WORKSPACE_DIR` 未设置时会自动走系统临时目录：macOS/Linux 解析为 `/tmp/expense-agent-workspace`，Windows 解析为 `%TEMP%\expense-agent-workspace`。

可选配置：

```bash
export JOB_BATCH_SIZE=20
export JOB_INTERVAL_MINUTES=60
export FIELD_RESULT_JSON='Agent Result JSON'
```

`JOB_BATCH_SIZE` 必须在 `1..500` 之间。

Job 会按 `record_id` 隔离工作目录：附件下载到 `downloads/{record_id}/`，Agent 输出到 `outputs/{record_id}/`。原始“发票原件”、“支付凭证”和“消费清单”字段不会被覆盖。

`--once` 返回码：

- `0`：本批次全部记录处理成功，或没有待处理记录。
- `1`：至少一条记录处理失败，或本机已有 Job 在运行。
- `2`：缺少必填环境变量等配置错误。

真实闭环验证前，请确认多维表格里至少有一条 `处理状态 = 待处理` 的记录，并且“发票原件”和“支付凭证”附件字段都已上传文件；如有小票拍照或美团消费项目截图，可上传到“消费清单”。运行 `--once` 后，检查该记录的新附件字段、状态、发票识别金额、支付凭证识别金额、开票日期、销售方、购买方、支付时间、费用类型、匹配结果、风险等级、处理说明和处理时间是否被写回。

## 测试

```bash
uv run --extra test pytest -q
```
