The skills shipped fictional examples (entity_type="TBMT", code TBMT-2026-001)
that fail against the live openclaw-egp-server: entity_type is exact-match and
stored lowercase, so "TBMT" returns 0 rows (verified: tbmt=722, TBMT=0).
Fixes:
- entity_type guidance -> lowercase tbmt/khlcnt/kqlcnt across all skills + README
- entity_code examples -> real eGP format IB<digits>-<version> (e.g. IB2600250575-00)
- index_status values -> indexed/changed/indexing/converting/converted/uploaded/deleted
(failed only exists at chunk level)
Exploit new entity columns now populated by the crawler:
- bid_close_date/bid_open_date (VN-time, UTC+7) -> dong/mo thau status computed in
Vietnam time, never host clock
- title/investor_name/status_code -> fill DISCOVERY candidate table directly
- version_no -> detect amendments/extensions (>"00")
Bump plugin to v0.3.0.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
"description":"RAG over Vietnamese government procurement documents (TBMT, KHLCNT, KQLCNT). Connects an OpenClaw agent to a running openclaw-egp-server instance via remote MCP.",
**Reply:** metadata + bảng files với cột `id` để user/agent có thể tham chiếu khi cần download.
**Reply:** metadata (tên gói, chủ đầu tư, đóng thầu, phiên bản) + bảng files với cột `id` để tham chiếu khi cần download.
## Đóng/mở thầu & phiên bản
- `bid_close_date`/`bid_open_date` là ISO **giờ VN (UTC+7, không có tz suffix)** → tính đang mở / sắp đóng / đã đóng theo giờ VN, không theo giờ máy chủ.
- `version_no` > `"00"` ⇒ hồ sơ đã có sửa đổi/gia hạn (notice được đăng lại). Khi user hỏi "có sửa đổi không", dùng trường này thay vì đoán.
## Anti-patterns
- ❌ Đừng đoán entity_code — phải hỏi nếu user mơ hồ.
@ -48,9 +48,10 @@ Phân loại câu hỏi vào 1 trong 4 intent:
Khi `intent = DISCOVERY`:
1. Extract keyword/filter từ câu hỏi: ngành, hàng hóa/dịch vụ, địa điểm, trạng thái, thời gian, khoảng giá.
2. Gọi `list_entities(entity_type?)` (filter loại nếu user chỉ định) + `search_procurement_docs(query=<keyword>, limit=10..20)`.
2. Gọi `list_entities(entity_type?)` (filter loại nếu user chỉ định — **giá trị LOWERCASE**`tbmt`/`khlcnt`/`kqlcnt`, viết hoa trả rỗng) + `search_procurement_docs(query=<keyword>, limit=10..20)`.
- `list_entities` trả `SELECT *` nên đã có sẵn `title`, `investor_name`, `bid_close_date`, `status_code`, `version_no` → **điền thẳng** vào bảng candidate, KHÔNG cần moi lại từ search.
3. Trả **bảng candidate** với cột:
- `rank` | `entity_type` | `entity_code` | `tên gói/thông báo/kế hoạch` | `bên mời thầu/chủ đầu tư` (nếu có) | `giá gói thầu` (nếu có) | `deadline/đóng thầu` (nếu có) | `trạng thái` (nếu có) | `highlight ngắn` (lý do match hoặc điểm đáng chú ý) | `citation/source`.
- `rank` | `entity_type` | `entity_code` | `tên gói` (`title`) | `chủ đầu tư` (`investor_name`, nếu có) | `giá gói thầu` (nếu có) | `đóng thầu` (`bid_close_date`, giờ VN) | `trạng thái` (mở/sắp đóng/đã đóng tính theo giờ VN, hoặc `status_code`) | `highlight ngắn` (lý do match) | `citation/source`.
4. **KHÔNG run full 5-part analysis** cho từng candidate.
5. Trước bảng, nếu có candidate deadline gấp / rủi ro nổi: thêm mục "**Ưu tiên xem trước**".
6. Sau bảng:
@ -81,11 +82,12 @@ Khi intent thuộc 3 nhóm này, render đủ **schema 5 phần** ở dưới.
#### Part 1 — Tóm tắt gói thầu
- Mã TBMT/E-TBMT
- Mã TBMT/E-TBMT (`entity_code`)
- Mã KHLCNT
- Tên gói thầu
- Chủ đầu tư / Bên mời thầu
- **Trạng thái**: đang mở / đã đóng / đã hủy / đã gia hạn. **Chỉ kết luận khi** có `bidCloseDate`, `status`, hoặc trường nguồn ghi rõ. Thiếu dữ liệu → "không xác định từ nguồn đã truy xuất".
- Tên gói thầu (`title`)
- Chủ đầu tư / Bên mời thầu (`investor_name`)
- **Trạng thái đóng/mở thầu**: ưu tiên cột **`bid_close_date`/`bid_open_date`** trên entity (`describe_entity`) — đây là ISO **giờ VN (UTC+7, không có tz suffix)**. Tính theo giờ VN: `đang mở` (deadline tương lai) / `sắp đóng` (~trong 48h) / `đã đóng` (đã qua). Có thể đối chiếu thêm `status_code`. **Chỉ kết luận khi** có `bid_close_date` hợp lệ hoặc `status_code` rõ. Thiếu cả hai → "không xác định từ nguồn đã truy xuất". KHÔNG bao giờ tính bằng giờ máy chủ.
- **Phiên bản/sửa đổi**: `version_no` > `"00"` ⇒ notice đã được đăng lại (có sửa đổi/gia hạn) — nêu rõ.
- 1 câu kết luận theo intent.
#### Part 2 — Thông tin KHLCNT / TBMT / E-HSMT quan trọng
@ -155,7 +157,7 @@ Khi rút gọn: header thêm hậu tố `(không phải trọng tâm câu hỏi,
- **Audit TBMT**: đủ mã / tên gói / bên mời / chủ đầu tư / mốc thời gian / bảo đảm / trạng thái?
- **Audit E-HSMT**: đủ Chỉ dẫn NT / Bảng dữ liệu / Tiêu chuẩn ĐG / YC kỹ thuật / Biểu mẫu / Điều kiện HĐ / Mẫu HĐ?
- **Khớp giữa 3 hồ sơ** (chỉ render khi CROSS_DOC_AUDIT hoặc đã tìm được related docs): bảng compare field-by-field, ✓ / ✗ / "không kiểm tra được".
- **Sửa đổi / gia hạn / làm rõ**: có/không, phiên bản mới nhất.
- **Sửa đổi / gia hạn / làm rõ**: dùng `version_no` trên entity (`"00"` = bản gốc; `> "00"` = đã đăng lại/sửa đổi). Nêu phiên bản hiện có. Lưu ý: hệ thống có thể chỉ giữ 1 snapshot — nếu web có phiên bản mới hơn (deadline đã đổi) mà entity còn `version_no` cũ, cảnh báo "có thể có bản cập nhật chưa crawl".
- **Kết luận audit**: ① Đủ để công khai / ② Cần bổ sung / ③ Rủi ro cần rà soát pháp lý — kèm lý do.
#### Part 5 — Rủi ro, điểm cần làm rõ & nguồn trích dẫn
@ -187,7 +189,7 @@ Khi rút gọn: header thêm hậu tố `(không phải trọng tâm câu hỏi,
3. **"Không thấy" ≠ "không có"**: thiếu trong retrieve KHÔNG có nghĩa thực tế gói thầu không có. Không chuyển nhãn.
4. **Đa bằng chứng**: check ≥ 3-5 results, không kết luận từ top-1. Nếu <3hits,expandquery/rephrasetrướckhinói"thiếuchứngcứ".
5. **Báo hit count khi < 3**: ghi rõ số hit thực tế, đánh dấu bằng chứng chưa đủ.
6. **Status conclusion gate**: KHÔNG kết luận "đang mở/đã đóng/đã hủy" nếu thiếu mốc thời gian / `status`.
6. **Status conclusion gate**: KHÔNG kết luận "đang mở/đã đóng/đã hủy" nếu thiếu mốc thời gian (`bid_close_date`) / `status_code`. Khi có `bid_close_date`, tính trạng thái theo **giờ VN (UTC+7)**, không bao giờ theo giờ máy chủ (lệch ~15h → sai kết luận).
7. **Conclusion strength gate**: cite yếu (≤ 1 cite, hoặc cite không match claim) → bỏ kết luận mạnh ("nên tham dự" / "đủ công khai" / "rủi ro pháp lý"), fallback sang "cần kiểm tra thêm" hoặc "không đủ dữ liệu để kết luận".
8. **Retrieval-weakness reporting**: results = [] hoặc `limitations` có warning → báo rõ giới hạn + đề xuất thêm file/keyword.
9. **Industry synonym expansion**: keyword mơ hồ (vd. "y tế" → thiết bị / dược / vật tư / dịch vụ) → có thể expand, NHƯNG bắt buộc log keyword đã dùng trong reply.