Commit Graph

16 Commits

Author SHA1 Message Date
hailin 60a74fc3b0 feat(agents): enforce QMAS 12-item eligibility threshold with 3-layer validation
根据2024年11月1日更新的优才计划政策,实现12项基本门槛评核准则的
系统级强制校验(需满足至少6项才具备申请资格)。

**Layer 1 — Assessment Expert Prompt (assessment-expert-prompt.ts):**
- QMAS评估新增强制性3步流程:门槛评核 → 成就计分制 → 综合计分制
- 12项评核准则逐一列出,含判定依据(年龄≤50、硕士/博士、STEM、
  双语能力、英文能力、≥5年工作经验、跨国/知名企业≥3年、
  特定行业≥3年、国际经验≥2年、年收入≥100万港币、
  业务实体盈利≥500万港币、上市公司)
- 每项判定为 met/not_met/unknown,unknown不计为符合
- 门槛不通过 → eligible=false, score上限29分
- 输出JSON新增 thresholdCheck 结构化字段(items数组+metCount+passed)

**Layer 2 — Code-level 后置校验 (immigration-tools.service.ts):**
- Step 4.5 安全网:解析评估结果后校验QMAS thresholdCheck一致性
- 门槛不通过但score>29 → 自动降级修正(score=29, eligible=false)
- 门槛通过但eligible=false且score>29 → 自动修正eligible=true
- 缺少thresholdCheck → 记录警告日志

**Layer 3 — Coordinator System Prompt (coordinator-system-prompt.ts):**
- Section 10.1 新增"基本门槛(2024年11月更新)"小节
- 明确说明门槛不通过者不具备申请资格(即使计分制达80分)
- 更新4条常见问题速答,融入门槛准则解释

**数据收集增强 (collection-expert-prompt.ts):**
- 新增3个附加字段:company_type、business_ownership、listed_company
- QMAS类别映射扩展,覆盖门槛评核12项所需全部数据点

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 07:40:47 -08:00
hailin f06ed09c3c feat(agents): v2.0 interruptible assessment with abort chain + admin toggle
Full abort signal chain: Gateway → ConversationService → Coordinator →
ToolExecutor → BaseSpecialist → Claude API stream. Admin can toggle between
v1 (post-completion re-evaluation) and v2 (interruptible) via REST API.

Changes:
- Gateway: add cancel_stream WebSocket handler + active stream tracking
- Gateway: abort active stream on client disconnect
- ConversationService: accept + forward AbortSignal
- CoordinatorAgentService: link external AbortSignal to internal controller,
  thread through tool executor, read assessment mode from Redis feature flag
- BaseSpecialistService: hard abort (throw) instead of soft break,
  add abort signal to Promise.race in callClaude(), abort stream on cancel
- ImmigrationToolsService: thread abortSignal to assessment expert
- AdminObservabilityController: GET/PUT feature-flags/assessment-mode
  (Redis-backed, defaults to v1)

v1 and v2 coexist — admin controls which mode is active.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 17:39:57 -08:00
hailin aa9f31ff20 feat(agents): v1.0 post-completion re-evaluation with forceReassess parameter
When users correct or update personal info after assessment completion,
Coordinator can now re-run run_professional_assessment with forceReassess: true
to bypass the 30-day dedup and produce an updated report.

Changes:
- Add forceReassess boolean param to run_professional_assessment tool definition
- Skip already_assessed check when forceReassess=true in handler
- Add prompt rules for identifying info corrections and triggering re-evaluation
- Document the re-evaluation flow in sections 3.5 and 4.4

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 17:30:24 -08:00
hailin a72e718510 fix(agents): add payment gate on invoke_assessment_expert + progress streaming for assessment
Two hardening fixes for the professional assessment pipeline:
1. Code-level payment verification before dispatching invoke_assessment_expert
   (prevents bypassing the prompt-only gate)
2. Thread onProgress callback through direct tool chain so run_professional_assessment
   streams agent_progress events during the 30-45s assessment expert execution

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 17:16:28 -08:00
hailin e809740fdb feat(agents): add run_professional_assessment tool with payment gate + artifact persistence
Replaces ad-hoc assessment flow with structured pipeline:
- Code-level payment verification (checks PAID ASSESSMENT order)
- Info completeness validation (age, nationality, education, work exp)
- Assessment expert invocation with result parsing
- Automatic persistence as UserArtifact (assessment_report type)
- 30-day dedup (existing report within 30 days returns cached)
- Frontend rendering for all status codes (completed, payment_required,
  info_incomplete, already_assessed, error)
- System prompt updated to mandate new tool for paid assessments
- Post-assessment auto-generation of checklist + timeline

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 17:01:56 -08:00
hailin 95f36752c9 feat(agents): add prompt-driven execution tools with DB persistence
Add 4 new tools (generate_document, manage_checklist, create_timeline,
query_user_artifacts) enabling the agent to create and manage persistent
user artifacts. Artifacts are saved to PostgreSQL and support dedup by
title, update-in-place, and cross-session querying. Frontend renders
rich UI cards for each artifact type.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 07:35:08 -08:00
hailin 43d4102e1f feat(agents): add query_user_profile tool for user info lookup
新增 query_user_profile 工具,让 AI agent 能回答用户关于自身信息的查询,
例如"这是我第几次咨询?"、"你记得我的信息吗?"、"我之前咨询过什么?"

## 问题背景
当用户问"这是我第几次跟你咨询?"时,AI 无法回答,因为没有任何工具
能查询用户的历史咨询数据。

## 实现方案:双层设计

### 第一层:被动上下文注入(Context Injector)
- context-injector.service.ts 注入 ConversationORM repo + TenantContextService
- buildConversationStatsBlock() 现在自动查询用户累计咨询次数
- 每次对话自动注入 `用户累计咨询次数: N 次(含本次对话)`
- 简单问题("这是第几次?")AI 可直接从上下文回答,零工具调用

### 第二层:主动工具调用(query_user_profile)
用户需要详细信息时,AI 调用此工具,返回完整档案:
- 咨询统计:累计次数、首次/最近咨询时间、类别分布
- 最近对话:最近 10 个对话的标题、类别、阶段
- 用户画像:系统记忆中的事实(学历/年龄/职业)、偏好、意图
- 订单统计:总单数、已支付、待支付

## 修改文件
- agents.module.ts: 添加 ConversationORM 到 TypeORM imports
- coordinator-tools.ts: 新增 query_user_profile 工具定义(只读)
- immigration-tools.service.ts: 注入 ConversationORM repo + TenantContextService,
  实现 queryUserProfile() 方法(并行查询对话+记忆+订单)
- coordinator-system-prompt.ts: 第3.3节添加工具文档和使用指引
- context-injector.service.ts: 注入 repo,conversation_stats 块添加累计咨询次数

## 依赖关系
- 无循环依赖:直接使用 TypeORM Repository<ConversationORM>(数据访问层),
  不依赖 ConversationService(避免 AgentsModule ↔ ConversationModule 循环)
- TenantContextService 全局可用,确保多租户隔离

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 12:17:23 -08:00
hailin 389f975e33 fix(payment): return paymentUrl from adapters, strip base64 from tool output
Alipay/WeChat adapters now return the source payment URL alongside the
QR base64. The generate_payment tool only returns paymentUrl (short text)
to Claude API — base64 qrCodeUrl is stripped to prevent AI from dumping
raw data:image into text responses. Frontend QRCodeSVG renders from
paymentUrl instead of base64.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 11:44:54 -08:00
hailin 9e9865acb0 fix(tools): 修复 coordinator-tools 与 immigration-tools 之间的 input_schema 不一致
## 问题

全链路检查发现 coordinator-tools.ts(Claude 实际使用的工具定义)与
immigration-tools.service.ts(实际执行器)之间有 4 处 input_schema 不一致,
会导致 Claude 发送的参数无法被正确解析。

## 修复

### check_off_topic
- coordinator 发 `query`,handler 读 `question`
- Fix: handler 同时支持 `query` 和 `question` 两个字段名

### collect_assessment_info
- coordinator 发 `{ userId, field, value }`(单字段模式)
- handler 读 `{ category, age, education, ... }`(批量模式)
- Fix: handler 同时支持两种输入格式

### generate_payment
- coordinator 旧 schema: `{ userId, serviceType, amount, description }`
- handler 需要: `{ serviceType, category, paymentMethod }`
- Fix: 更新 coordinator schema 为 `{ serviceType, category, paymentMethod }`
  - serviceType enum 改为 ASSESSMENT/CONSULTATION/DOCUMENT_REVIEW(匹配 payment-service)
  - 添加 category enum 和 paymentMethod enum
  - 移除 userId(从 context 获取)和 amount(由 payment-service 定价)

### save_user_memory
- coordinator 旧 schema 多余 `userId`(handler 用 context.userId)
- coordinator 发 `importance` 但 handler 不读
- handler 支持 `category` 但 coordinator 未定义
- Fix: coordinator schema 移除 userId,移除 importance,添加 category

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 01:31:38 -08:00
hailin a3f2be078b feat(payment): P2 — 订单管理增强,支持取消订单和订单详情查询
## 后端改动

### PaymentClientService 增强
- 新增 `getOrderDetail(orderId)` — 获取完整订单信息(含支付详情)
- 新增 `cancelOrder(orderId)` — 取消未支付订单(调用 POST /orders/:id/cancel)

### 新增 cancel_order 工具
- 工具定义: 接收 orderId,取消未支付订单
- 实现: 调用 PaymentClientService.cancelOrder()
- 成功返回 { success, orderId, status, message }
- 失败返回友好错误信息(如"只有未支付的订单才能取消")
- coordinator-tools.ts 注册,concurrency map 标记 false(写操作)

## 前端改动

### cancel_order 结果渲染
- 成功: 绿色卡片 + CheckCircle 图标 + 成功提示
- 失败: 红色卡片 + AlertCircle 图标 + 错误原因
- 显示订单号

## 注意事项
- payment-service 暂无退款 API,cancel_order 仅限未支付订单
- 退款功能待 payment-service 侧实现后再扩展

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 01:23:28 -08:00
hailin df754ce8b8 feat(payment): P0 — 支付闭环,Agent 可创建真实订单并生成支付二维码
## 后端改动

### 新增 PaymentClientService
- 新建 `infrastructure/payment/payment-client.service.ts`
  - HTTP 客户端封装,调用 payment-service API(端口 3002)
  - 方法: createOrder, createPayment, checkPaymentStatus, getOrderStatus, getUserOrders
  - 基于 native fetch,模式与 KnowledgeClientService 一致
- 新建 `infrastructure/payment/payment.module.ts`
- AgentsModule 导入 PaymentModule

### 重写 generate_payment 工具
- 删除所有 MOCK 数据(fake orderId, placeholder QR URL)
- 实际调用 payment-service: createOrder → createPayment → 返回真实 QR URL
- 返回 orderId, paymentId, qrCodeUrl, paymentUrl, expiresAt

### 新增 check_payment_status 工具
- 查询订单支付状态(调用 payment-service GET /orders/:id/status)
- 返回 status, statusLabel(中文映射), paidAt
- 在 coordinator-tools.ts 和 concurrency map 中注册(只读 safe=true)

### 新增 query_order_history 工具
- 查询用户历史订单列表(调用 payment-service GET /orders)
- 返回 orders 数组含 orderId, serviceType, amount, status, createdAt
- 在 coordinator-tools.ts 和 concurrency map 中注册(只读 safe=true)

## 前端改动

### QR 码渲染
- 安装 qrcode.react 4.2.0
- ToolCallResult 组件使用 QRCodeSVG 渲染真实二维码
- 支持 qrCodeUrl(二维码)和 paymentUrl(跳转链接)两种支付方式
- 显示订单号、金额、过期时间

### 支付状态卡片
- check_payment_status 结果渲染为彩色状态卡片
- 已支付=绿色, 待支付=黄色, 已取消=红色, 已退款=橙色

### 订单历史列表
- query_order_history 结果渲染为订单列表卡片
- 每行显示: 类别、日期、金额、状态标签

### WebSocket 工具事件处理
- tool_result 事件收集到 pendingToolResults(chatStore 新增状态)
- stream_end 时将 toolResults 注入消息 metadata.toolCalls
- stream_start 时清空 pendingToolResults

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 01:17:14 -08:00
hailin ce13c8b770 fix(agents): remove official website referral from fallback labels, use neutral disclaimer
Replace "请以入境处官方信息为准" / "建议向香港入境处官网核实" with
"基于AI训练数据,可能不是最新信息" across all fallback messages.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 22:10:45 -08:00
hailin 04dbc61131 feat(agents): add capability boundary guardrails — input gate, cascading fallback, output gate rules
Four guardrail improvements to enforce agent capability boundaries:

1. Cascading Fallback (Fix 1+4):
   - Rewrite searchKnowledge() in immigration-tools.service.ts with 3-tier fallback:
     KB (similarity >= 0.55) → Web Search → Built-in Knowledge (clearly labeled)
   - Rewrite executeTool() in policy-expert.service.ts to use retrieveKnowledge()
     with confidence threshold; returns [KB_EMPTY]/[KB_LOW_CONFIDENCE]/[KB_ERROR]
     markers so the model knows to label source reliability

2. Input Gate (Fix 2):
   - New InputGateService using Haiku for lightweight pre-classification
   - Classifications: ON_TOPIC / OFF_TOPIC (threshold >= 0.7) / HARMFUL (>= 0.6)
   - Short messages (< 5 chars) fast-path to ON_TOPIC
   - Gate failure is non-fatal (allows message through)
   - Integrated in CoordinatorAgentService.sendMessage() before agent loop entry
   - OFF_TOPIC/HARMFUL messages get fixed responses without entering agent loop

3. Output Gate Enhancement (Fix 3):
   - Add TOPIC_BOUNDARY and NO_FABRICATION to EvaluationRuleType
   - TOPIC_BOUNDARY: regex detection for code blocks, programming keywords,
     AI identity exposure, off-topic indicators in agent responses
   - NO_FABRICATION: detects policy claims without policy_expert invocation
     or source markers; ensures factual claims are knowledge-backed
   - Both rule types are admin-configurable (zero rules = zero checks)
   - No DB migration needed (ruleType is varchar(50))

Files changed:
- NEW: agents/coordinator/input-gate.service.ts
- MOD: agents/coordinator/coordinator-agent.service.ts (inject InputGate + gate check)
- MOD: agents/agents.module.ts (register InputGateService)
- MOD: agents/coordinator/evaluation-gate.service.ts (2 new evaluators)
- MOD: domain/entities/evaluation-rule.entity.ts (2 new rule types)
- MOD: agents/specialists/policy-expert.service.ts (RAG confidence threshold)
- MOD: claude/tools/immigration-tools.service.ts (cascading fallback)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 21:59:10 -08:00
hailin 4c125f3276 feat(agent): add 4 real-time tools for enhanced agent capabilities
Add the following real-time tools to ImmigrationToolsService:
- get_current_datetime: Get current date/time with timezone support
- web_search: Search internet for latest immigration news/policies (Google CSE)
- get_exchange_rate: Query real-time currency exchange rates (for investment immigration)
- fetch_immigration_news: Fetch latest immigration announcements

All tools include graceful degradation with fallback responses when external APIs are unavailable.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 00:46:55 -08:00
hailin 911132ab3e feat(agent): upgrade to Level 3 with real RAG, Memory and Evolution integration
## Summary
Upgrade iConsulting from Level 2 (48 points) to Level 3 (68 points) by
implementing real service-to-service integration between conversation-service
and knowledge-service.

## New Files
- knowledge-client.service.ts: HTTP client for knowledge-service APIs
- knowledge.module.ts: NestJS module for KnowledgeClientService
- AGENT_EVALUATION_REPORT.md: Agent capability evaluation report
- LEVEL3_UPGRADE_PLAN.md: Upgrade plan and completion report

## Changes

### RAG Integration
- search_knowledge tool now calls /api/v1/knowledge/retrieve
- check_off_topic tool calls /api/v1/knowledge/check-off-topic
- Results include real vector similarity search from knowledge base

### Memory Integration
- save_user_memory writes to PostgreSQL + Neo4j via knowledge-service
- collect_assessment_info saves user data to long-term memory
- generate_payment records payment intent to user memory
- New get_user_context tool retrieves user's historical memories

### Evolution Integration
- getAccumulatedExperience() fetches approved system experiences
- sendMessage() dynamically injects experiences into system prompt
- System learns from approved experiences across all conversations

## Expected Score Improvement
| Dimension  | Before | After | Delta |
|------------|--------|-------|-------|
| Tool Use   | 14/20  | 18/20 | +4    |
| Memory     | 12/20  | 16/20 | +4    |
| RAG        | 10/20  | 16/20 | +6    |
| Evolution  | 8/20   | 14/20 | +6    |
| Total      | 48     | 68    | +20   |

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 23:45:58 -08:00
hailin a7add8ff90 Initial commit: iConsulting 香港移民咨询智能客服系统
项目架构:
- Monorepo (pnpm + Turborepo)
- 后端: NestJS 微服务 + Claude Agent SDK
- 前端: React + Vite + Ant Design

包含服务:
- conversation-service: 对话服务 (Claude AI)
- user-service: 用户认证服务
- payment-service: 支付服务 (支付宝/微信/Stripe)
- knowledge-service: 知识库服务 (RAG + Neo4j)
- evolution-service: 自我进化服务
- web-client: 用户前端
- admin-client: 管理后台

基础设施:
- PostgreSQL + Redis + Neo4j
- Kong API Gateway
- Nginx 反向代理
- Docker Compose 部署配置

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-09 00:01:12 -08:00