新增官方 inline Agent「发票整理助手」(`invoice-organizer`)。
Adds an official inline Agent, **Invoice Organizer**, that turns
invoices scattered across
mailboxes and local folders into a reconcilable, reusable ledger.
## 它做什么 / What it does
七步固定流程,每一步幂等:**接入检查 → 收集 → 解析 → 去重 → 归档 → 台账 → 报告**。
- **收集**:从已接入的邮箱(Gmail / Outlook / IMAP)找出候选发票邮件,附件用 `MailOperations` 的
`save_to` 直接落盘,base64 不进模型上下文
- **解析**:OFD(三个结构化来源分别处理)、PDF 文字层、扫描件走视觉;每个字段带 `extractedBy` 与置信度
- **去重**:发票号码为主键,跨格式识别同一张票(PDF 与照片、重复下载);近重复不自动合并
- **归档**:`归档/年/月/YYYYMMDD_销售方_金额_发票号码.ext`,原件一个不动
- **台账**:xlsx 四张表(明细 / 月度汇总 / 按销售方汇总 / 异常),发票号码强制文本格式;
装不上 openpyxl 时降级为 UTF-8 BOM CSV
- **报告**:Markdown 月度报告,收尾固定报五个计数(范围 / 候选 / 成功 / 待复核 / 失败)
- **自动化**:邮件规则 `agent_handle` + `ManageSchedule` 定时出账
## 明确的能力边界 / Explicit boundaries
- **不做发票真伪查验**,也不暗示做过——只做形式校验与勾稽校验,给出官方查验平台入口让用户自己核验
- **不删除、不移动、不转发用户的邮件**
- **票面内容不外流**:不外发、不代发、不上传第三方接口或在线查验站点
- **不做汇率换算**;不承诺「已找全」,只报「在给定范围内找到 N 封候选、成功解析 M 张」
## 结构 / Structure
```
agents/invoice-organizer/
├── agent.json persona.md principles.md LICENSE
├── USAGE.zh-CN.md USAGE.en-US.md
├── catalog-metadata.v1.json # availability: listing-only(可安装化见下)
├── assets/avatar.webp
└── skills/
├── invoice-workflow/ # 七步总纲、目录布局、落盘顺序、去重主键、幂等
├── invoice-extract/ # 三种载体的解析细则、置信度分档、特殊票据
│ └── references/票面文本形态.md
├── invoice-ledger/ # 台账结构、人民币约定(覆盖 xlsx 技能的默认口径)
│ └── references/月度报告模板.md
└── invoice-automation/ # 邮件规则与定时调度的参数模板与排查
```
`manifest.json` 的 `stats.totalAgents` 3 → 4。
## 事实性核对 / Fact-checking
技能里引用的**每一个**端点 / 工具名 / 参数名 / 返回字段都对着 DesireCore 主仓库实现逐条核对过,
并经过一轮对抗式 review。review 抓到的、已修正的主要事实错误:
- OFD 一节原本只覆盖 2020 年式样;已改为按**三个来源**分述
(内嵌附件 / 2024 数电票的 `Tags/CustomTag.xml` 标引 / `DocInfo/CustomDatas`),
键名从 `Buyer/BuyerName` 改为真实的点号路径 `Buyer.BuyerName`,置信度按来源分档
- **`DocInfo/CustomDatas` 的「合计金额」是不含税金额**,误当 `totalAmount` 会让每张 2024
数电票少记税额
——已写成硬规则
- Gmail 本地缓存搜索的 `q` **实际只按主题过滤**(正文过滤在主题收窄之后才跑),
原文写成「搜主题与正文」会导致静默漏邮件
- 「轮询只覆盖收件箱」只对 IMAP 成立,Gmail / Outlook 是整个邮箱
- `POST /rules/{id}/test` 走另一份内联实现、**没有 `matches_regex` 分支**,
不能用它验证正则规则
- 邮件列表项里 Gmail / IMAP **是带** `attachments[]` 的,只有 Outlook 不带;
`labelIds` 是 Gmail 专有
## 真机验证 / Verified on a live instance
在 dev 实例上以一句话指令处理 31 个混合文件(数电票 / 旧版票 / OFD / 扫描件 / 行程单,
外加重复、近重复、作废、零额与 4 个非发票负样本):
- 23 张归档,字段与夹具 ground truth **逐条吻合**
- 4 个非发票**全部正确拒绝**并写明理由(施工许可证 / 对账单 / 技术服务合同 / 邮件通知)
- 4 个跨格式重复(3 张扫描件 + 1 次重复下载)**全部靠发票号码主键识破**,隔离而非删除
- 近重复正确未合并;作废票归档但不计入合计;低置信度定额发票标为待复核
- 台账 xlsx 四张表、报告含五个计数、`SendUserMessage` 带附件交付
- `待整理/` 31 个原件一个未动
## 校验 / Validation
```
validate_catalog_metadata.py --require-complete 0 error, agents=4, sidecars=74 exit=0
validate-i18n.py 0 error exit=0
translate.py --check exit=0
gen-collection-children.py --check exit=0
```
129 条 warning 全部来自 `skills/*` 的存量条目,改前改后一字不差,`invoice-organizer` 零命中。
另核实:`agent.json` 过 `marketAgentSchema`(详情页)与收窄后过
`agentConfigSchema`(安装),
persona / principles 的 6 个 canonical key 用平台真实解析器全部解得出,全树敏感信息扫描通过
(所有公司名 / 税号 / 银行账号均为 `示例`/`示范`/`虚构`/`样例` 前缀的合成值)。
## 后续 / Follow-up
本 PR 为 `availability: listing-only`。可安装化需要把 `agent.json#contentSource` 与
sidecar 的 `provenance.content` **逐字一致地** pin 到本 PR 的合并 commit,
并补 `governance.compliance` 与 `timestamps.reviewedAt`——那是紧接着的第二个 PR。
7.5 KiB
Invoice Organizer · Usage
Check three things before installing
1. A mailbox is connected. This is the only step that requires you: authorize an account (Gmail, Outlook or IMAP) in the DesireCore mail interface. Without one, the Agent can still parse files you drop into its work directory yourself, but the collection step is unavailable.
2. There is a work directory you can actually find. After installation the Agent automatically receives a default workspace, but that path is hard to locate in a file manager. On the first conversation it will suggest registering a visible directory (for example ~/Documents/invoices) and making it primary — just agree. Deliverables land there and appear in DesireCore's file workbench.
3. It does not verify invoice authenticity. No official verification channel is available to it. It performs format and arithmetic checks only (required fields present, amounts reconcile, the document is internally consistent) and hands you the State Taxation Administration's national VAT invoice verification platform so you can check the number yourself. If verification is what you need, this Agent is not the answer.
How to use it
Once installed, just say what you want in plain language:
- "Sort out August's invoices" — the full pipeline: intake, extraction, dedupe, archive, ledger, report
- "How much is this month's spend?" — summary only, no mailbox re-scan
- "Have I already recorded this invoice?" — an index lookup, answered immediately
- "Export August's invoices to Excel" — rebuilds the ledger from the index without re-parsing anything
- "From now on, post new invoices automatically" — sets up the mail rule and the scheduled job, after explaining exactly what will happen
Relative dates like "last month" are converted to explicit start and end dates and read back to you before any work starts — that one step avoids most year-boundary mistakes.
What you get
One new directory under your work directory:
发票/ (invoices)
├── 台账.xlsx (ledger; 台账.csv when the xlsx dependencies are unavailable)
├── 报告/2024-08.md (reports)
├── 归档/2024/08/20240815_<seller>_1959.98_24312000000000020002.pdf (archive, by year/month)
├── _inbox/ downloaded, not yet processed
├── _quarantine/ parse failures and non-invoices, each with a .reason.txt
└── .index/ dedupe index — do not edit by hand
The directory and file names are Chinese, matching the invoices themselves; the English glosses above
are only for reading this page. Look for 发票/ under your work directory.
The ledger has four sheets: line items, monthly summary, per-seller summary, and exceptions. Amounts follow RMB conventions (two decimal places always; a zero-amount invoice shows as ¥0.00 rather than being hidden), and invoice numbers and tax IDs are stored as text so Excel cannot turn them into 2.4312E+19.
Every monthly report opens with a one-line conclusion before any detail, and each entry under "needs your attention" carries a concrete action rather than just a description.
Documents it handles
- PDF: fully digital VAT e-invoices (the nationwide platform format used since 2023, both ordinary and special), legacy VAT electronic ordinary invoices, railway e-ticket reimbursement vouchers (both the old and new layouts), air transport e-ticket itineraries, taxi and ride-hailing receipts
- OFD: reads the structured invoice data carried inside the package. A 2020-style invoice ships a complete national-standard invoice XML in the package — those values are written by the issuing system rather than guessed from the layout, so that path gets full confidence. A 2024 fully-digital invoice carries only invoice tags, which cannot supply the invoice code or the per-line item breakdown; those are recovered from the layout text and confidence is lowered to match. When neither is present it falls back to layout text
- Scans and images: JPG, PNG, WebP, and scanned PDFs with no text layer, handed to the vision model with confidence lowered accordingly
None of this requires you to install anything. Only the .xlsx ledger may need Python with openpyxl and pandas; when they are missing it writes a UTF-8 BOM CSV instead (so non-Latin text opens correctly in Excel) and tells you it degraded.
About approvals (read this before expecting unattended runs)
Organizing invoices calls confirmation-gated tools constantly — reading the mailbox, downloading attachments, writing files — and under the default approval mode each call raises an approval card. Processing a few dozen invoices raises a lot of them in a row. That is by design, not a fault.
If you want genuinely unattended operation (a ledger built overnight on a schedule, new mail posted automatically), you need to switch this Agent's execution-approval mode to allow-all in its settings. The cost is that its file writes and mail calls stop asking each time. Note that the "always allow" button does not currently take effect for these tools — pressing it will not stop the cards.
What it will not do
- Never deletes, moves or forwards your mail. Mailbox cleanup stays with you
- No accounting entries, no tax filing, no input-tax-credit judgements
- No currency conversion. A foreign-currency settlement is still priced in RMB on the face of the invoice; the original amount and the rate used are copied verbatim into the notes, never converted and never totalled separately
- Never merges suspected duplicates on its own (numbers differing by one digit with every other field identical); they are listed for you to decide
- Never invents invoice fields. Whatever cannot be extracted is left empty, the original is quarantined, and the reason is stated
- Never claims to have found everything, only that within the stated range it found N candidate messages and successfully parsed M invoices
Known limits
- On IMAP accounts, mail rules only cover the inbox. If you are on IMAP and your invoice mail is auto-filed into another folder, the rule will not fire; in that case ask the Agent in conversation to scan that folder. Gmail and Outlook poll the whole mailbox and are not affected
- The local cached search matches keywords against the subject only. Mail whose subject never says "invoice" and only mentions it in the body ("You have a new electronic voucher") will not surface that way. On Gmail the Agent switches to Gmail's own server-side search, which does cover bodies; on Outlook and IMAP it has to pull the messages locally and scan them one by one, which is slower over a wide range. It states in its summary which of the two it used
- Outlook and IMAP have no server-side search, so messages must be pulled locally before filtering. Over a wide range that is noticeably slower than Gmail, where the native search syntax narrows the set in one call
- Password-protected PDFs cannot be opened. Some invoicing platforms send them with the password in the message body. For now you need to decrypt the file yourself and drop it into
_inbox/, and the next run will pick it up - Void detection relies on the text layer. A void stamp that exists only as an image may go undetected. Void invoices get their own column in the ledger — worth a glance
Privacy
Invoices carry company names, taxpayer IDs, bank accounts and travel details. All of it stays in your local work directory and ledger. This Agent has no outbound channel and never replies to or forwards mail on your behalf; when you want to send the ledger to someone, it hands the file back to you and you decide where it goes.