@wowok/agent-mcp 2.3.14 → 2.3.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/config/index.d.ts +1 -0
- package/dist/config/index.js +1 -0
- package/dist/config/runtime.d.ts +26 -0
- package/dist/config/runtime.js +217 -0
- package/dist/customer/industry-risks.d.ts +36 -0
- package/dist/customer/industry-risks.js +424 -0
- package/dist/customer/info-puzzle.d.ts +102 -0
- package/dist/customer/info-puzzle.js +312 -0
- package/dist/customer/order-monitor.d.ts +75 -0
- package/dist/customer/order-monitor.js +327 -0
- package/dist/customer/order-strategy.d.ts +36 -0
- package/dist/customer/order-strategy.js +373 -0
- package/dist/customer/post-purchase.d.ts +42 -0
- package/dist/customer/post-purchase.js +350 -0
- package/dist/customer/reminder-system.d.ts +42 -0
- package/dist/customer/reminder-system.js +295 -0
- package/dist/customer/risk-assessment.d.ts +8 -0
- package/dist/customer/risk-assessment.js +337 -0
- package/dist/customer/types.d.ts +193 -0
- package/dist/customer/types.js +13 -0
- package/dist/customer/user-preferences.d.ts +67 -0
- package/dist/customer/user-preferences.js +451 -0
- package/dist/experience/experience-reuse.d.ts +10 -0
- package/dist/experience/experience-reuse.js +103 -0
- package/dist/experience/index.d.ts +6 -0
- package/dist/experience/index.js +5 -0
- package/dist/experience/intent-distill.d.ts +3 -0
- package/dist/experience/intent-distill.js +83 -0
- package/dist/experience/realtime-feedback.d.ts +5 -0
- package/dist/experience/realtime-feedback.js +77 -0
- package/dist/experience/types.d.ts +50 -0
- package/dist/experience/types.js +1 -0
- package/dist/experience/user-profile.d.ts +25 -0
- package/dist/experience/user-profile.js +171 -0
- package/dist/index.js +570 -186
- package/dist/knowledge/acquisition-flywheel.d.ts +50 -0
- package/dist/knowledge/acquisition-flywheel.js +183 -0
- package/dist/knowledge/arbitration-trust.d.ts +24 -0
- package/dist/knowledge/arbitration-trust.js +117 -0
- package/dist/knowledge/audit-rules.d.ts +28 -0
- package/dist/knowledge/audit-rules.js +141 -0
- package/dist/knowledge/demand-matching.d.ts +29 -0
- package/dist/knowledge/demand-matching.js +132 -0
- package/dist/knowledge/dynamic-pricing.d.ts +31 -0
- package/dist/knowledge/dynamic-pricing.js +87 -0
- package/dist/knowledge/flywheel-loop.d.ts +87 -0
- package/dist/knowledge/flywheel-loop.js +378 -0
- package/dist/knowledge/glossary.d.ts +18 -0
- package/dist/knowledge/glossary.js +209 -0
- package/dist/knowledge/index.d.ts +64 -0
- package/dist/knowledge/index.js +66 -0
- package/dist/knowledge/industry-evolution.d.ts +82 -0
- package/dist/knowledge/industry-evolution.js +323 -0
- package/dist/knowledge/industry-generalizer.d.ts +17 -0
- package/dist/knowledge/industry-generalizer.js +381 -0
- package/dist/knowledge/industry-registry.d.ts +49 -0
- package/dist/knowledge/industry-registry.js +167 -0
- package/dist/knowledge/intent-metrics.d.ts +42 -0
- package/dist/knowledge/intent-metrics.js +566 -0
- package/dist/knowledge/process-model.d.ts +24 -0
- package/dist/knowledge/process-model.js +160 -0
- package/dist/knowledge/reputation-rules.d.ts +42 -0
- package/dist/knowledge/reputation-rules.js +99 -0
- package/dist/knowledge/reward-templates.d.ts +25 -0
- package/dist/knowledge/reward-templates.js +125 -0
- package/dist/knowledge/safety-rules.d.ts +36 -0
- package/dist/knowledge/safety-rules.js +171 -0
- package/dist/knowledge/tool-constraints.d.ts +30 -0
- package/dist/knowledge/tool-constraints.js +185 -0
- package/dist/knowledge/trust-metrics.d.ts +37 -0
- package/dist/knowledge/trust-metrics.js +138 -0
- package/dist/loop-engineering/diagnose.d.ts +3 -2
- package/dist/loop-engineering/diagnose.js +94 -0
- package/dist/loop-engineering/improve.d.ts +1 -1
- package/dist/loop-engineering/improve.js +52 -1
- package/dist/project/graph.d.ts +71 -0
- package/dist/project/graph.js +314 -0
- package/dist/project/index.d.ts +62 -0
- package/dist/project/index.js +167 -0
- package/dist/project/namespace.d.ts +62 -0
- package/dist/project/namespace.js +181 -0
- package/dist/project/query.d.ts +40 -0
- package/dist/project/query.js +110 -0
- package/dist/safety/confirm-gate.d.ts +15 -0
- package/dist/safety/confirm-gate.js +44 -0
- package/dist/safety/index.d.ts +3 -0
- package/dist/safety/index.js +3 -0
- package/dist/safety/preview.d.ts +2 -0
- package/dist/safety/preview.js +36 -0
- package/dist/schema/call/allocation.d.ts +15 -0
- package/dist/schema/call/arbitration.d.ts +111 -96
- package/dist/schema/call/base.d.ts +1070 -44
- package/dist/schema/call/base.js +69 -1
- package/dist/schema/call/bridge.d.ts +709 -52
- package/dist/schema/call/bridge.js +13 -2
- package/dist/schema/call/contact.d.ts +15 -0
- package/dist/schema/call/demand.d.ts +69 -54
- package/dist/schema/call/guard.d.ts +125 -80
- package/dist/schema/call/handler.d.ts +3 -0
- package/dist/schema/call/handler.js +14 -0
- package/dist/schema/call/machine.d.ts +830 -800
- package/dist/schema/call/order.d.ts +15 -0
- package/dist/schema/call/payment.d.ts +15 -0
- package/dist/schema/call/permission.d.ts +15 -0
- package/dist/schema/call/personal.d.ts +15 -0
- package/dist/schema/call/progress.d.ts +15 -0
- package/dist/schema/call/proof.d.ts +42 -12
- package/dist/schema/call/proof.js +3 -3
- package/dist/schema/call/repository.d.ts +91 -76
- package/dist/schema/call/reward.d.ts +45 -30
- package/dist/schema/call/semantic.d.ts +1 -0
- package/dist/schema/call/semantic.js +217 -0
- package/dist/schema/call/service.d.ts +407 -392
- package/dist/schema/call/treasury.d.ts +15 -0
- package/dist/schema/common/index.js +3 -3
- package/dist/schema/local/index.d.ts +228 -72
- package/dist/schema/local/index.js +33 -6
- package/dist/schema/messenger/index.d.ts +668 -50
- package/dist/schema/messenger/index.js +9 -0
- package/dist/schema/operations.d.ts +1693 -1369
- package/dist/schema/operations.js +2 -2
- package/dist/schema/query/index.d.ts +1614 -1614
- package/dist/schema/query/index.js +30 -27
- package/dist/schemas/account_operation.output.json +25 -16
- package/dist/schemas/account_operation.schema.json +1 -1
- package/dist/schemas/bridge_operation.output.json +520 -0
- package/dist/schemas/bridge_operation.schema.json +15 -0
- package/dist/schemas/guard2file.schema.json +15 -0
- package/dist/schemas/index.json +1 -1
- package/dist/schemas/local_info_operation.output.json +23 -0
- package/dist/schemas/local_info_operation.schema.json +1 -1
- package/dist/schemas/local_mark_operation.output.json +24 -1
- package/dist/schemas/local_mark_operation.schema.json +4 -4
- package/dist/schemas/machineNode2file.schema.json +15 -0
- package/dist/schemas/messenger_operation.output.json +528 -0
- package/dist/schemas/onchain_operations.output.json +350 -16
- package/dist/schemas/onchain_operations.schema.json +96 -23
- package/dist/schemas/onchain_operations_allocation.schema.json +15 -0
- package/dist/schemas/onchain_operations_arbitration.schema.json +15 -0
- package/dist/schemas/onchain_operations_contact.schema.json +15 -0
- package/dist/schemas/onchain_operations_demand.schema.json +15 -0
- package/dist/schemas/onchain_operations_gen_passport.schema.json +30 -0
- package/dist/schemas/onchain_operations_guard.schema.json +15 -0
- package/dist/schemas/onchain_operations_machine.schema.json +81 -23
- package/dist/schemas/onchain_operations_order.schema.json +15 -0
- package/dist/schemas/onchain_operations_payment.schema.json +15 -0
- package/dist/schemas/onchain_operations_permission.schema.json +15 -0
- package/dist/schemas/onchain_operations_personal.schema.json +15 -0
- package/dist/schemas/onchain_operations_progress.schema.json +15 -0
- package/dist/schemas/onchain_operations_repository.schema.json +15 -0
- package/dist/schemas/onchain_operations_reward.schema.json +15 -0
- package/dist/schemas/onchain_operations_service.schema.json +15 -0
- package/dist/schemas/onchain_operations_treasury.schema.json +15 -0
- package/dist/schemas/onchain_table_data.output.json +221 -69
- package/dist/schemas/onchain_table_data.schema.json +2 -2
- package/package.json +2 -2
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { InfoPuzzle, RiskScore, RiskLevel } from "./types.js";
|
|
2
|
+
import { CUSTOMER_INTELLIGENCE_VERSION } from "./types.js";
|
|
3
|
+
export declare function riskLevelFromScore(score: number): RiskLevel;
|
|
4
|
+
export declare function riskLevelLabel(level: RiskLevel): string;
|
|
5
|
+
export declare function riskLevelEmoji(level: RiskLevel): string;
|
|
6
|
+
export declare function assessRisk(puzzle: InfoPuzzle): RiskScore;
|
|
7
|
+
export declare function passesRiskThreshold(score: RiskScore, minLevel?: RiskLevel): boolean;
|
|
8
|
+
export { CUSTOMER_INTELLIGENCE_VERSION };
|
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
import { RISK_LEVELS, RISK_DIMENSION_MAX, CUSTOMER_INTELLIGENCE_VERSION } from "./types.js";
|
|
2
|
+
export function riskLevelFromScore(score) {
|
|
3
|
+
const entry = RISK_LEVELS.find((l) => score >= l.min);
|
|
4
|
+
return entry?.level ?? "high";
|
|
5
|
+
}
|
|
6
|
+
export function riskLevelLabel(level) {
|
|
7
|
+
const entry = RISK_LEVELS.find((l) => l.level === level);
|
|
8
|
+
return entry ? `${entry.color} ${entry.label}` : "🔴 高风险";
|
|
9
|
+
}
|
|
10
|
+
export function riskLevelEmoji(level) {
|
|
11
|
+
const entry = RISK_LEVELS.find((l) => l.level === level);
|
|
12
|
+
return entry?.color ?? "🔴";
|
|
13
|
+
}
|
|
14
|
+
function assessWorkflowRisk(puzzle) {
|
|
15
|
+
const wf = puzzle.workflow_analysis;
|
|
16
|
+
const checks = [];
|
|
17
|
+
const hasRefund = wf?.has_refund_path ?? false;
|
|
18
|
+
checks.push({
|
|
19
|
+
id: "wf_refund_path",
|
|
20
|
+
dimension: "workflow",
|
|
21
|
+
description: "存在退款路径(100%→Order Allocator)",
|
|
22
|
+
weight: 10,
|
|
23
|
+
passed: hasRefund,
|
|
24
|
+
advice: hasRefund ? undefined : "⚠️ 无退款路径:若交付失败,资金可能无法回收。建议下单前通过 Messenger 与商家协商退款条款并写入 WTS。",
|
|
25
|
+
});
|
|
26
|
+
const hasArb = wf?.has_arbitration_path ?? false;
|
|
27
|
+
checks.push({
|
|
28
|
+
id: "wf_arbitration_path",
|
|
29
|
+
dimension: "workflow",
|
|
30
|
+
description: "存在仲裁路径",
|
|
31
|
+
weight: 10,
|
|
32
|
+
passed: hasArb,
|
|
33
|
+
advice: hasArb ? undefined : "⚠️ 无仲裁路径:纠纷无法升级到第三方仲裁。建议要求商家绑定 Arbitration 服务后再下单。",
|
|
34
|
+
});
|
|
35
|
+
const userOps = wf?.user_operable_forwards ?? 0;
|
|
36
|
+
checks.push({
|
|
37
|
+
id: "wf_user_operable",
|
|
38
|
+
dimension: "workflow",
|
|
39
|
+
description: "至少 1 条用户可操作 Forward",
|
|
40
|
+
weight: 8,
|
|
41
|
+
passed: userOps > 0,
|
|
42
|
+
advice: userOps > 0 ? undefined : "🔴 流程中无任何用户可操作步骤:订单进度完全依赖商家,你将处于被动地位。",
|
|
43
|
+
});
|
|
44
|
+
const deadEnds = wf?.dead_end_nodes ?? [];
|
|
45
|
+
const noDeadEnds = deadEnds.length === 0;
|
|
46
|
+
checks.push({
|
|
47
|
+
id: "wf_no_dead_ends",
|
|
48
|
+
dimension: "workflow",
|
|
49
|
+
description: "无潜在死端节点",
|
|
50
|
+
weight: 4,
|
|
51
|
+
passed: noDeadEnds,
|
|
52
|
+
advice: noDeadEnds ? undefined : `⚠️ 检测到 ${deadEnds.length} 个潜在死端节点:${deadEnds.join(", ")}。这些节点的所有出口都依赖商家操作。`,
|
|
53
|
+
});
|
|
54
|
+
const machineUsable = wf ? (wf.machine_published && !wf.machine_paused) : false;
|
|
55
|
+
checks.push({
|
|
56
|
+
id: "wf_machine_usable",
|
|
57
|
+
dimension: "workflow",
|
|
58
|
+
description: "Machine 已发布且未暂停",
|
|
59
|
+
weight: 3,
|
|
60
|
+
passed: machineUsable,
|
|
61
|
+
advice: machineUsable ? undefined : "⚠️ Machine 未发布或已暂停:流程可能尚未生效或被商家主动暂停。",
|
|
62
|
+
});
|
|
63
|
+
const score = checks.reduce((sum, c) => sum + (c.passed ? c.weight : 0), 0);
|
|
64
|
+
return { name: "workflow", score, max_score: RISK_DIMENSION_MAX.workflow, checks };
|
|
65
|
+
}
|
|
66
|
+
function assessFundRisk(puzzle) {
|
|
67
|
+
const fund = puzzle.fund_safety;
|
|
68
|
+
const checks = [];
|
|
69
|
+
let compScore = 0;
|
|
70
|
+
let compAdvice;
|
|
71
|
+
if (fund) {
|
|
72
|
+
if (fund.compensation_covers_order) {
|
|
73
|
+
compScore = 10;
|
|
74
|
+
}
|
|
75
|
+
else if (fund.compensation_ratio > 0) {
|
|
76
|
+
compScore = Math.round(fund.compensation_ratio * 10);
|
|
77
|
+
compAdvice = `⚠️ 赔偿金仅覆盖订单金额的 ${Math.round(fund.compensation_ratio * 100)}%,不足以全额赔付。`;
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
compScore = 0;
|
|
81
|
+
compAdvice = "🔴 无赔偿金:商家未设置 compensation_fund,订单失败时无自动赔付来源。";
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
compScore = 5;
|
|
86
|
+
}
|
|
87
|
+
checks.push({
|
|
88
|
+
id: "fund_compensation",
|
|
89
|
+
dimension: "fund",
|
|
90
|
+
description: "赔偿金充足度(覆盖订单金额)",
|
|
91
|
+
weight: 10,
|
|
92
|
+
passed: compScore >= 7,
|
|
93
|
+
advice: compAdvice,
|
|
94
|
+
});
|
|
95
|
+
const hasRefundAllocator = fund?.refund_allocator_exists ?? false;
|
|
96
|
+
checks.push({
|
|
97
|
+
id: "fund_refund_allocator",
|
|
98
|
+
dimension: "fund",
|
|
99
|
+
description: "存在 100%→Order 退款 Allocator",
|
|
100
|
+
weight: 8,
|
|
101
|
+
passed: hasRefundAllocator,
|
|
102
|
+
advice: hasRefundAllocator ? undefined : "⚠️ 未检测到 100%→Order Allocator:退款需要商家手动操作或通过仲裁裁定。",
|
|
103
|
+
});
|
|
104
|
+
const priceOk = fund ? fund.price_anomaly === "none" : true;
|
|
105
|
+
checks.push({
|
|
106
|
+
id: "fund_price_normal",
|
|
107
|
+
dimension: "fund",
|
|
108
|
+
description: "价格无异常(与赔偿金和市场价比对)",
|
|
109
|
+
weight: 4,
|
|
110
|
+
passed: priceOk,
|
|
111
|
+
advice: priceOk ? undefined : `⚠️ 价格异常(${fund?.price_anomaly}):可能存在欺诈定价或异常低价诱惑。`,
|
|
112
|
+
});
|
|
113
|
+
const lockSafe = fund?.lock_duration_safe ?? true;
|
|
114
|
+
checks.push({
|
|
115
|
+
id: "fund_lock_safe",
|
|
116
|
+
dimension: "fund",
|
|
117
|
+
description: "赔偿金锁定期合理(≥7天或无锁定)",
|
|
118
|
+
weight: 3,
|
|
119
|
+
passed: lockSafe,
|
|
120
|
+
advice: lockSafe ? undefined : "⚠️ 赔偿金锁定期过短:商家可能随时撤回资金。",
|
|
121
|
+
});
|
|
122
|
+
const naiveScore = checks.reduce((sum, c) => sum + (c.passed ? c.weight : 0), 0);
|
|
123
|
+
const score = fund && !fund.compensation_covers_order && fund.compensation_ratio > 0
|
|
124
|
+
? Math.min(RISK_DIMENSION_MAX.fund, naiveScore + compScore - (compScore >= 7 ? 10 : 0))
|
|
125
|
+
: naiveScore;
|
|
126
|
+
return { name: "fund", score, max_score: RISK_DIMENSION_MAX.fund, checks };
|
|
127
|
+
}
|
|
128
|
+
function assessTrustRisk(puzzle) {
|
|
129
|
+
const trust = puzzle.trust_signals;
|
|
130
|
+
const checks = [];
|
|
131
|
+
const arbIndependent = trust?.arbitration_independent ?? true;
|
|
132
|
+
checks.push({
|
|
133
|
+
id: "trust_arb_independent",
|
|
134
|
+
dimension: "trust",
|
|
135
|
+
description: "仲裁方与商家无利益关联",
|
|
136
|
+
weight: 6,
|
|
137
|
+
passed: arbIndependent,
|
|
138
|
+
advice: arbIndependent ? undefined : "🔴 仲裁方与商家为同一地址:仲裁公正性无法保证。",
|
|
139
|
+
});
|
|
140
|
+
let reviewPassed = false;
|
|
141
|
+
let reviewAdvice;
|
|
142
|
+
if (trust && trust.review_total > 0) {
|
|
143
|
+
const likeRate = trust.like_rate;
|
|
144
|
+
if (likeRate >= 0.85) {
|
|
145
|
+
reviewPassed = true;
|
|
146
|
+
}
|
|
147
|
+
else if (likeRate >= 0.6) {
|
|
148
|
+
reviewPassed = true;
|
|
149
|
+
reviewAdvice = `⚠️ 好评率 ${Math.round(likeRate * 100)}%,存在一定争议。`;
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
reviewPassed = false;
|
|
153
|
+
reviewAdvice = `🔴 好评率仅 ${Math.round(likeRate * 100)}%(${trust.review_likes}/${trust.review_total}),差评较多。`;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
else if (trust) {
|
|
157
|
+
reviewPassed = true;
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
reviewPassed = true;
|
|
161
|
+
}
|
|
162
|
+
checks.push({
|
|
163
|
+
id: "trust_review_reputation",
|
|
164
|
+
dimension: "trust",
|
|
165
|
+
description: "评价声誉良好(好评率 ≥60%)",
|
|
166
|
+
weight: 5,
|
|
167
|
+
passed: reviewPassed,
|
|
168
|
+
advice: reviewAdvice,
|
|
169
|
+
});
|
|
170
|
+
const trustScore = trust?.trust_score ?? 50;
|
|
171
|
+
const trustPassed = trustScore >= 50;
|
|
172
|
+
checks.push({
|
|
173
|
+
id: "trust_score",
|
|
174
|
+
dimension: "trust",
|
|
175
|
+
description: `综合信任分 ≥50(当前 ${trustScore})`,
|
|
176
|
+
weight: 4,
|
|
177
|
+
passed: trustPassed,
|
|
178
|
+
advice: trustPassed ? undefined : `🔴 综合信任分仅 ${trustScore}/100,建议寻找更高信任度的商家。`,
|
|
179
|
+
});
|
|
180
|
+
const hasContact = trust?.has_contact ?? false;
|
|
181
|
+
const hasMessenger = trust?.has_messenger ?? false;
|
|
182
|
+
checks.push({
|
|
183
|
+
id: "trust_contact",
|
|
184
|
+
dimension: "trust",
|
|
185
|
+
description: "商家有可联系的 Messenger 通道",
|
|
186
|
+
weight: 5,
|
|
187
|
+
passed: hasContact && hasMessenger,
|
|
188
|
+
advice: (hasContact && hasMessenger) ? undefined : "🔴 商家无可联系通道(um 为空):无法进行 pre-order 协商或售后沟通。",
|
|
189
|
+
});
|
|
190
|
+
const score = checks.reduce((sum, c) => sum + (c.passed ? c.weight : 0), 0);
|
|
191
|
+
return { name: "trust", score, max_score: RISK_DIMENSION_MAX.trust, checks };
|
|
192
|
+
}
|
|
193
|
+
function assessBehaviorRisk(puzzle) {
|
|
194
|
+
const beh = puzzle.merchant_behavior;
|
|
195
|
+
const checks = [];
|
|
196
|
+
let trendPassed = false;
|
|
197
|
+
let trendAdvice;
|
|
198
|
+
if (beh) {
|
|
199
|
+
if (beh.recent_trend === "improving") {
|
|
200
|
+
trendPassed = true;
|
|
201
|
+
}
|
|
202
|
+
else if (beh.recent_trend === "stable") {
|
|
203
|
+
trendPassed = true;
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
206
|
+
trendPassed = false;
|
|
207
|
+
trendAdvice = "🔴 商家近期争议率上升:履约质量可能在恶化。";
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
else {
|
|
211
|
+
trendPassed = true;
|
|
212
|
+
}
|
|
213
|
+
checks.push({
|
|
214
|
+
id: "behavior_trend",
|
|
215
|
+
dimension: "behavior",
|
|
216
|
+
description: "近期履约趋势稳定或改善",
|
|
217
|
+
weight: 6,
|
|
218
|
+
passed: trendPassed,
|
|
219
|
+
advice: trendAdvice,
|
|
220
|
+
});
|
|
221
|
+
const completionPassed = beh ? beh.completed_rate >= 0.85 : true;
|
|
222
|
+
checks.push({
|
|
223
|
+
id: "behavior_completion_rate",
|
|
224
|
+
dimension: "behavior",
|
|
225
|
+
description: "订单完成率 ≥85%",
|
|
226
|
+
weight: 4,
|
|
227
|
+
passed: completionPassed,
|
|
228
|
+
advice: completionPassed ? undefined : `🔴 完成率仅 ${Math.round((beh?.completed_rate ?? 0) * 100)}%:高于平均的订单以失败告终。`,
|
|
229
|
+
});
|
|
230
|
+
const disputeOk = beh ? beh.dispute_rate <= 0.1 : true;
|
|
231
|
+
checks.push({
|
|
232
|
+
id: "behavior_low_dispute",
|
|
233
|
+
dimension: "behavior",
|
|
234
|
+
description: "争议率 ≤10%",
|
|
235
|
+
weight: 4,
|
|
236
|
+
passed: disputeOk,
|
|
237
|
+
advice: disputeOk ? undefined : `⚠️ 争议率 ${Math.round((beh?.dispute_rate ?? 0) * 100)}%:高于行业平均水平。`,
|
|
238
|
+
});
|
|
239
|
+
const arbLossOk = beh ? beh.arb_loss_rate <= 0.3 : true;
|
|
240
|
+
checks.push({
|
|
241
|
+
id: "behavior_arb_loss",
|
|
242
|
+
dimension: "behavior",
|
|
243
|
+
description: "仲裁败诉率 ≤30%",
|
|
244
|
+
weight: 3,
|
|
245
|
+
passed: arbLossOk,
|
|
246
|
+
advice: arbLossOk ? undefined : `🔴 仲裁败诉率 ${Math.round((beh?.arb_loss_rate ?? 0) * 100)}%:商家多次在仲裁中败诉,存在违规倾向。`,
|
|
247
|
+
});
|
|
248
|
+
const noRedFlags = beh ? beh.red_flags.length === 0 : true;
|
|
249
|
+
checks.push({
|
|
250
|
+
id: "behavior_no_red_flags",
|
|
251
|
+
dimension: "behavior",
|
|
252
|
+
description: "无行为 red_flags",
|
|
253
|
+
weight: 3,
|
|
254
|
+
passed: noRedFlags,
|
|
255
|
+
advice: noRedFlags ? undefined : `⚠️ 检测到行为警示信号:${beh?.red_flags.join(", ")}`,
|
|
256
|
+
});
|
|
257
|
+
const score = checks.reduce((sum, c) => sum + (c.passed ? c.weight : 0), 0);
|
|
258
|
+
return { name: "behavior", score, max_score: RISK_DIMENSION_MAX.behavior, checks };
|
|
259
|
+
}
|
|
260
|
+
export function assessRisk(puzzle) {
|
|
261
|
+
const dimensions = [
|
|
262
|
+
assessWorkflowRisk(puzzle),
|
|
263
|
+
assessFundRisk(puzzle),
|
|
264
|
+
assessTrustRisk(puzzle),
|
|
265
|
+
assessBehaviorRisk(puzzle),
|
|
266
|
+
];
|
|
267
|
+
const total = dimensions.reduce((sum, d) => sum + d.score, 0);
|
|
268
|
+
const level = riskLevelFromScore(total);
|
|
269
|
+
const redFlags = [];
|
|
270
|
+
for (const dim of dimensions) {
|
|
271
|
+
for (const check of dim.checks) {
|
|
272
|
+
if (!check.passed && check.advice && check.advice.startsWith("🔴")) {
|
|
273
|
+
redFlags.push(`[${dim.name}] ${check.description}: ${check.advice}`);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
if (puzzle.workflow_analysis?.risk_signals.length) {
|
|
278
|
+
for (const sig of puzzle.workflow_analysis.risk_signals) {
|
|
279
|
+
redFlags.push(`[workflow_signal] ${sig}`);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
if (puzzle.merchant_behavior?.red_flags.length) {
|
|
283
|
+
for (const f of puzzle.merchant_behavior.red_flags) {
|
|
284
|
+
redFlags.push(`[behavior_flag] ${f}`);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
const advice = generateAdvice(puzzle, total, level, dimensions);
|
|
288
|
+
return {
|
|
289
|
+
total,
|
|
290
|
+
level,
|
|
291
|
+
dimensions,
|
|
292
|
+
red_flags: redFlags,
|
|
293
|
+
advice,
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
function generateAdvice(puzzle, total, level, dimensions) {
|
|
297
|
+
const advice = [];
|
|
298
|
+
const emoji = riskLevelEmoji(level);
|
|
299
|
+
const levelEntry = RISK_LEVELS.find((l) => l.level === level);
|
|
300
|
+
advice.push(`${emoji} 综合风险评分:${total}/100(${levelEntry?.label ?? "未知"})`);
|
|
301
|
+
if (level === "high") {
|
|
302
|
+
advice.push("🚫 建议放弃此订单:风险水平过高,资金安全无法保证。");
|
|
303
|
+
}
|
|
304
|
+
else if (level === "medium_high") {
|
|
305
|
+
advice.push("⚠️ 建议谨慎下单:务必通过 Messenger 协商补充条款,并要求生成 WTS 凭证。");
|
|
306
|
+
}
|
|
307
|
+
else if (level === "medium_low") {
|
|
308
|
+
advice.push("✅ 可以下单:建议持续关注订单进度,保留沟通记录。");
|
|
309
|
+
}
|
|
310
|
+
else {
|
|
311
|
+
advice.push("✅ 安全订单:可放心下单,仍建议启用订单监控提醒。");
|
|
312
|
+
}
|
|
313
|
+
const sortedDims = [...dimensions].sort((a, b) => (a.score / a.max_score) - (b.score / b.max_score));
|
|
314
|
+
for (const dim of sortedDims) {
|
|
315
|
+
const ratio = dim.max_score > 0 ? dim.score / dim.max_score : 0;
|
|
316
|
+
if (ratio < 0.5) {
|
|
317
|
+
const failedChecks = dim.checks.filter((c) => !c.passed);
|
|
318
|
+
if (failedChecks.length > 0) {
|
|
319
|
+
advice.push(`📊 ${dim.name} 维度 ${dim.score}/${dim.max_score}:${failedChecks.length} 项未通过。`);
|
|
320
|
+
const critical = failedChecks.find((c) => c.advice?.startsWith("🔴"));
|
|
321
|
+
if (critical?.advice)
|
|
322
|
+
advice.push(critical.advice);
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
if (puzzle.completeness < 0.8) {
|
|
327
|
+
advice.push(`ℹ️ 信息完整度仅 ${Math.round(puzzle.completeness * 100)}%,缺失:${puzzle.gaps.join(", ") || "无"}。建议补充数据后再决策。`);
|
|
328
|
+
}
|
|
329
|
+
return advice;
|
|
330
|
+
}
|
|
331
|
+
export function passesRiskThreshold(score, minLevel = "medium_high") {
|
|
332
|
+
const order = ["high", "medium_high", "medium_low", "low"];
|
|
333
|
+
const minIdx = order.indexOf(minLevel);
|
|
334
|
+
const actualIdx = order.indexOf(score.level);
|
|
335
|
+
return actualIdx >= minIdx;
|
|
336
|
+
}
|
|
337
|
+
export { CUSTOMER_INTELLIGENCE_VERSION };
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
export type PuzzleDepth = "browse" | "evaluate" | "preorder" | "monitor";
|
|
2
|
+
export interface ServiceBasics {
|
|
3
|
+
service_id: string;
|
|
4
|
+
name: string;
|
|
5
|
+
bPublished: boolean;
|
|
6
|
+
bPaused: boolean;
|
|
7
|
+
price: string;
|
|
8
|
+
price_raw: bigint;
|
|
9
|
+
token_type: string;
|
|
10
|
+
sales_count: number;
|
|
11
|
+
machine_id?: string;
|
|
12
|
+
buy_guard_id?: string;
|
|
13
|
+
customer_required_count: number;
|
|
14
|
+
arbitrations_count: number;
|
|
15
|
+
compensation_fund_balance: bigint;
|
|
16
|
+
compensation_lock_duration: number;
|
|
17
|
+
um_id?: string;
|
|
18
|
+
has_wip: boolean;
|
|
19
|
+
wip_verified: boolean;
|
|
20
|
+
}
|
|
21
|
+
export interface WorkflowAnalysis {
|
|
22
|
+
machine_published: boolean;
|
|
23
|
+
machine_paused: boolean;
|
|
24
|
+
total_nodes: number;
|
|
25
|
+
total_forwards: number;
|
|
26
|
+
user_operable_forwards: number;
|
|
27
|
+
provider_only_forwards: number;
|
|
28
|
+
guard_gated_forwards: number;
|
|
29
|
+
has_refund_path: boolean;
|
|
30
|
+
has_arbitration_path: boolean;
|
|
31
|
+
has_milestone_nodes: boolean;
|
|
32
|
+
dead_end_nodes: string[];
|
|
33
|
+
terminal_nodes: string[];
|
|
34
|
+
risk_signals: string[];
|
|
35
|
+
}
|
|
36
|
+
export interface FundSafety {
|
|
37
|
+
has_order_allocator: boolean;
|
|
38
|
+
has_refund_allocator: boolean;
|
|
39
|
+
allocator_count: number;
|
|
40
|
+
refund_allocator_exists: boolean;
|
|
41
|
+
surplus_to_provider: boolean;
|
|
42
|
+
user_path_has_allocator: boolean;
|
|
43
|
+
compensation_covers_order: boolean;
|
|
44
|
+
compensation_ratio: number;
|
|
45
|
+
lock_duration_safe: boolean;
|
|
46
|
+
price_anomaly: "none" | "low" | "high";
|
|
47
|
+
}
|
|
48
|
+
export interface TrustSignals {
|
|
49
|
+
arbitration_independent: boolean;
|
|
50
|
+
arbitration_count: number;
|
|
51
|
+
arbitration_paused: boolean;
|
|
52
|
+
review_likes: number;
|
|
53
|
+
review_dislikes: number;
|
|
54
|
+
review_verified_count: number;
|
|
55
|
+
review_total: number;
|
|
56
|
+
like_rate: number;
|
|
57
|
+
trust_score: number;
|
|
58
|
+
trust_level: "high_risk" | "caution" | "moderate" | "trusted";
|
|
59
|
+
has_contact: boolean;
|
|
60
|
+
has_messenger: boolean;
|
|
61
|
+
}
|
|
62
|
+
export interface MerchantBehavior {
|
|
63
|
+
total_orders: number;
|
|
64
|
+
completed_rate: number;
|
|
65
|
+
dispute_rate: number;
|
|
66
|
+
refund_rate: number;
|
|
67
|
+
arb_loss_rate: number;
|
|
68
|
+
repeat_buyer_rate: number;
|
|
69
|
+
recent_trend: "improving" | "stable" | "declining";
|
|
70
|
+
red_flags: string[];
|
|
71
|
+
}
|
|
72
|
+
export interface MarketContext {
|
|
73
|
+
similar_services_count: number;
|
|
74
|
+
avg_price: bigint;
|
|
75
|
+
min_price: bigint;
|
|
76
|
+
max_price: bigint;
|
|
77
|
+
price_percentile: number;
|
|
78
|
+
supply_demand_ratio: number;
|
|
79
|
+
}
|
|
80
|
+
export interface InfoPuzzle {
|
|
81
|
+
service_id: string;
|
|
82
|
+
service_basics: ServiceBasics;
|
|
83
|
+
workflow_analysis?: WorkflowAnalysis;
|
|
84
|
+
fund_safety?: FundSafety;
|
|
85
|
+
trust_signals?: TrustSignals;
|
|
86
|
+
merchant_behavior?: MerchantBehavior;
|
|
87
|
+
market_context?: MarketContext;
|
|
88
|
+
completeness: number;
|
|
89
|
+
gaps: string[];
|
|
90
|
+
assembled_at: number;
|
|
91
|
+
}
|
|
92
|
+
export type RiskDimensionName = "workflow" | "fund" | "trust" | "behavior";
|
|
93
|
+
export interface RiskCheck {
|
|
94
|
+
id: string;
|
|
95
|
+
dimension: RiskDimensionName;
|
|
96
|
+
description: string;
|
|
97
|
+
weight: number;
|
|
98
|
+
passed: boolean;
|
|
99
|
+
advice?: string;
|
|
100
|
+
}
|
|
101
|
+
export interface RiskDimensionScore {
|
|
102
|
+
name: RiskDimensionName;
|
|
103
|
+
score: number;
|
|
104
|
+
max_score: number;
|
|
105
|
+
checks: RiskCheck[];
|
|
106
|
+
}
|
|
107
|
+
export type RiskLevel = "low" | "medium_low" | "medium_high" | "high";
|
|
108
|
+
export interface RiskScore {
|
|
109
|
+
total: number;
|
|
110
|
+
level: RiskLevel;
|
|
111
|
+
dimensions: RiskDimensionScore[];
|
|
112
|
+
red_flags: string[];
|
|
113
|
+
advice: string[];
|
|
114
|
+
}
|
|
115
|
+
export interface UserPreferences {
|
|
116
|
+
price_sensitivity: "low" | "medium" | "high";
|
|
117
|
+
budget_range?: {
|
|
118
|
+
min: bigint;
|
|
119
|
+
max: bigint;
|
|
120
|
+
};
|
|
121
|
+
value_orientation: "quality" | "balanced" | "budget";
|
|
122
|
+
discount_sensitivity: number;
|
|
123
|
+
delivery_speed_priority: "urgent" | "normal" | "flexible";
|
|
124
|
+
max_acceptable_cycle: number;
|
|
125
|
+
response_time_expectation: number;
|
|
126
|
+
preferred_region?: string;
|
|
127
|
+
timezone?: string;
|
|
128
|
+
language?: string;
|
|
129
|
+
merchant_preference: "established" | "emerging" | "neutral";
|
|
130
|
+
min_order_history: number;
|
|
131
|
+
bargain_hunting: number;
|
|
132
|
+
reward_seeking: boolean;
|
|
133
|
+
referral_participation: boolean;
|
|
134
|
+
communication_style: "formal" | "casual" | "friendly";
|
|
135
|
+
transparency_demand: number;
|
|
136
|
+
after_sales_expectation: "full" | "basic" | "minimal";
|
|
137
|
+
risk_appetite: "conservative" | "balanced" | "aggressive";
|
|
138
|
+
min_trust_score: number;
|
|
139
|
+
require_arbitration: boolean;
|
|
140
|
+
require_compensation_fund: boolean;
|
|
141
|
+
preferred_industries: string[];
|
|
142
|
+
preferred_tokens: string[];
|
|
143
|
+
preferred_merchants: string[];
|
|
144
|
+
}
|
|
145
|
+
export type ReminderPriority = "required" | "recommended" | "info" | "reminder";
|
|
146
|
+
export interface Reminder {
|
|
147
|
+
id: string;
|
|
148
|
+
stage: "browse" | "evaluate" | "preorder" | "in_progress" | "complete" | "after_sale";
|
|
149
|
+
priority: ReminderPriority;
|
|
150
|
+
message: string;
|
|
151
|
+
action?: string;
|
|
152
|
+
}
|
|
153
|
+
export type GameScenario = "info_asymmetry" | "fund_safety" | "refund_dispute" | "arbitration_fairness" | "pricing" | "delivery_sla" | "quality_verification" | "after_sales";
|
|
154
|
+
export interface GameStrategy {
|
|
155
|
+
scenario: GameScenario;
|
|
156
|
+
merchant_tactic: string;
|
|
157
|
+
user_strategy: string;
|
|
158
|
+
nash_equilibrium: string;
|
|
159
|
+
}
|
|
160
|
+
export interface CustomerAdvice {
|
|
161
|
+
risk_score?: number;
|
|
162
|
+
risk_level?: RiskLevel;
|
|
163
|
+
recommendations: string[];
|
|
164
|
+
reminders: Reminder[];
|
|
165
|
+
preference_match?: {
|
|
166
|
+
score: number;
|
|
167
|
+
matches: string[];
|
|
168
|
+
mismatches: string[];
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
export declare const CUSTOMER_INTELLIGENCE_VERSION = 1;
|
|
172
|
+
export declare const RISK_LEVELS: readonly [{
|
|
173
|
+
readonly min: 85;
|
|
174
|
+
readonly level: "low";
|
|
175
|
+
readonly label: "低风险";
|
|
176
|
+
readonly color: "🟢";
|
|
177
|
+
}, {
|
|
178
|
+
readonly min: 70;
|
|
179
|
+
readonly level: "medium_low";
|
|
180
|
+
readonly label: "中低风险";
|
|
181
|
+
readonly color: "🟡";
|
|
182
|
+
}, {
|
|
183
|
+
readonly min: 50;
|
|
184
|
+
readonly level: "medium_high";
|
|
185
|
+
readonly label: "中高风险";
|
|
186
|
+
readonly color: "🟠";
|
|
187
|
+
}, {
|
|
188
|
+
readonly min: 0;
|
|
189
|
+
readonly level: "high";
|
|
190
|
+
readonly label: "高风险";
|
|
191
|
+
readonly color: "🔴";
|
|
192
|
+
}];
|
|
193
|
+
export declare const RISK_DIMENSION_MAX: Record<RiskDimensionName, number>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export const CUSTOMER_INTELLIGENCE_VERSION = 1;
|
|
2
|
+
export const RISK_LEVELS = [
|
|
3
|
+
{ min: 85, level: "low", label: "低风险", color: "🟢" },
|
|
4
|
+
{ min: 70, level: "medium_low", label: "中低风险", color: "🟡" },
|
|
5
|
+
{ min: 50, level: "medium_high", label: "中高风险", color: "🟠" },
|
|
6
|
+
{ min: 0, level: "high", label: "高风险", color: "🔴" },
|
|
7
|
+
];
|
|
8
|
+
export const RISK_DIMENSION_MAX = {
|
|
9
|
+
workflow: 35,
|
|
10
|
+
fund: 25,
|
|
11
|
+
trust: 20,
|
|
12
|
+
behavior: 20,
|
|
13
|
+
};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { UserPreferences } from "./types.js";
|
|
2
|
+
import { CUSTOMER_INTELLIGENCE_VERSION } from "./types.js";
|
|
3
|
+
export type Industry = "freelance" | "rental" | "education" | "travel" | "subscription" | "retail";
|
|
4
|
+
export declare const SUPPORTED_INDUSTRIES: Industry[];
|
|
5
|
+
export interface IndustryTemplate {
|
|
6
|
+
max_acceptable_cycle: number;
|
|
7
|
+
response_time_expectation: number;
|
|
8
|
+
require_arbitration: boolean;
|
|
9
|
+
require_compensation_fund: boolean;
|
|
10
|
+
risk_appetite: UserPreferences["risk_appetite"];
|
|
11
|
+
delivery_speed_priority: UserPreferences["delivery_speed_priority"];
|
|
12
|
+
after_sales_expectation: UserPreferences["after_sales_expectation"];
|
|
13
|
+
}
|
|
14
|
+
export declare function getDefaultPreferences(industry?: Industry): UserPreferences;
|
|
15
|
+
export declare function getIndustryTemplate(industry: Industry): IndustryTemplate;
|
|
16
|
+
export interface OrderHistoryEntry {
|
|
17
|
+
service_id: string;
|
|
18
|
+
service_owner?: string;
|
|
19
|
+
industry?: string;
|
|
20
|
+
price: bigint;
|
|
21
|
+
avg_market_price: bigint;
|
|
22
|
+
used_discount: boolean;
|
|
23
|
+
used_referral: boolean;
|
|
24
|
+
has_arbitration: boolean;
|
|
25
|
+
has_compensation: boolean;
|
|
26
|
+
risk_score_at_purchase?: number;
|
|
27
|
+
used_messenger: boolean;
|
|
28
|
+
messenger_messages?: number;
|
|
29
|
+
completed: boolean;
|
|
30
|
+
has_dispute: boolean;
|
|
31
|
+
timestamp: number;
|
|
32
|
+
}
|
|
33
|
+
export interface PreferenceInference {
|
|
34
|
+
preferences: UserPreferences;
|
|
35
|
+
confidence: Record<keyof UserPreferences, number>;
|
|
36
|
+
signals: string[];
|
|
37
|
+
}
|
|
38
|
+
export declare function inferPreferences(history: OrderHistoryEntry[], basePrefs?: UserPreferences): PreferenceInference;
|
|
39
|
+
export interface ServiceForMatching {
|
|
40
|
+
service_id: string;
|
|
41
|
+
price: bigint;
|
|
42
|
+
token_type: string;
|
|
43
|
+
avg_market_price?: bigint;
|
|
44
|
+
estimated_cycle_days?: number;
|
|
45
|
+
estimated_response_hours?: number;
|
|
46
|
+
merchant_region?: string;
|
|
47
|
+
merchant_order_history_count: number;
|
|
48
|
+
merchant_age: "established" | "emerging" | "unknown";
|
|
49
|
+
has_arbitration: boolean;
|
|
50
|
+
has_compensation_fund: boolean;
|
|
51
|
+
has_reward_activity: boolean;
|
|
52
|
+
has_discount: boolean;
|
|
53
|
+
risk_score: number;
|
|
54
|
+
trust_score: number;
|
|
55
|
+
requires_messenger: boolean;
|
|
56
|
+
after_sales_support_level: "full" | "basic" | "minimal";
|
|
57
|
+
}
|
|
58
|
+
export interface PreferenceMatchResult {
|
|
59
|
+
score: number;
|
|
60
|
+
matches: string[];
|
|
61
|
+
mismatches: string[];
|
|
62
|
+
warnings: string[];
|
|
63
|
+
}
|
|
64
|
+
export declare function matchServiceToPreferences(service: ServiceForMatching, prefs: UserPreferences): PreferenceMatchResult;
|
|
65
|
+
export declare function mergePreferences(inferred: UserPreferences, manual: Partial<UserPreferences>): UserPreferences;
|
|
66
|
+
export declare function validatePreferences(prefs: UserPreferences): string[];
|
|
67
|
+
export { CUSTOMER_INTELLIGENCE_VERSION };
|