@apetechs/ai-tool
v0.2.0
Published
Khai báo API của module NestJS thành tool cho APE AI Assistant (@AiTool, /ai/manifest)
Readme
ape-ai-tool
Khai báo API có sẵn của một module NestJS thành tool cho APE AI Assistant (ape-erp-chatbot). Module chỉ gắn decorator;
guard, RBAC, DTO giữ nguyên. Hợp đồng đầy đủ: ape-erp-chatbot/docs/tool-contract.md.
Dùng
// app.module.ts
AiToolModule.forRoot({ module: 'eam', manifestKey: () => process.env.AI_MANIFEST_KEY, instructions: '...' });
// controller có sẵn
@DefPost('list')
@RequirePermissions([PERMISSION_CODES.ASSET.VIEW])
@AiTool({
name: 'list_assets',
description: 'Tìm thiết bị theo trạng thái… Không dùng để xem work order.',
mode: 'read',
input: { fields: ['serialNumber', 'operationalStatus'] }, // lấy schema từ @ApiProperty của DTO
output: { listPath: 'data', totalPath: 'total', fields: ['id', 'assetName'] },
recordUrl: '/assets/asset-instances?id={id}',
})
list(@Body() dto: ListAssetDto) {}
// một handler, sau middleware xác thực của module
@DefPost('context')
@AiToolContext()
context() { /* trả { tenantId, userId, tools: [...] } — xem ape_eam_api/src/modules/client/ai-tool */ }
// nút AI ở màn nghiệp vụ (0.2.0): handler trả dữ liệu, assistant đưa cho LLM với `instructions`, nhận object đúng `output`
@DefPost('pr-summary')
@RequirePermissions([PERMISSION_CODES.PURCHASE_REQUEST.VIEW])
@AiTask({
name: 'pr_summary',
description: 'Tóm tắt một PR',
instructions: 'Bạn là trợ lý mua hàng… Chỉ dùng dữ liệu được đưa.',
output: PrSummaryOutputDto, // class có @ApiProperty → outputSchema
})
prSummary(@Body() dto: IdDto) { return this.service.prSummaryContext(dto.id) }GET /<global prefix>/ai/manifest+ headerx-ai-manifest-key→ danh sách tool, path đầy đủ (global prefix + prefix module của@ChildModule+ controller + action), JSON Schema tham số,version= sha256 nội dung.- Manifest có
tasks[](0.2.0):name,instructions,method,path,inputSchema,outputSchema. Assistant gọi quaPOST /tasks/<name>; task không bao giờ lẫn vàotools, một handler chỉ mang một trong@AiTool/@AiTask/@AiToolContext. AiToolRegistry.tools()/tasks()trả thêmhandler,controllerđể module tự kiểm quyền từng tool bằng guard của mình.- Field trong
input.fieldsthiếu@ApiProperty, tên tool trùng, hoặc hai@AiToolContext()⇒ lỗi khi dựng manifest.
Lệnh
yarn install --frozen-lockfile
yarn typecheck && yarn test && yarn build
./publish.sh # đăng nhập npm nếu cần, kiểm, publish, rồi cài vào ape_eam_apiSmoke test đầu-cuối
examples/chat-smoke.mjs (Node 22, không phụ thuộc gì) đi đúng đường assistant sẽ đi: manifest → context → LLM qua OpenRouter
→ gọi tool bằng token user → rút gọn kết quả. Cách chạy ghi ở đầu file.
