@wowok/agent-mcp 2.3.18 → 2.4.3

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.
Files changed (121) hide show
  1. package/dist/customer/industry-risks.js +31 -31
  2. package/dist/customer/order-monitor.js +57 -57
  3. package/dist/customer/order-strategy.js +89 -89
  4. package/dist/customer/post-purchase.js +97 -97
  5. package/dist/customer/reminder-system.js +26 -26
  6. package/dist/customer/risk-assessment.js +46 -46
  7. package/dist/customer/types.d.ts +4 -4
  8. package/dist/customer/types.js +4 -4
  9. package/dist/customer/user-preferences.js +50 -50
  10. package/dist/experience/intent-distill.js +6 -6
  11. package/dist/index.d.ts +2 -2
  12. package/dist/index.js +11 -1624
  13. package/dist/knowledge/acquisition-flywheel.js +64 -64
  14. package/dist/knowledge/arbitration-trust.js +10 -10
  15. package/dist/knowledge/demand-matching.js +8 -8
  16. package/dist/knowledge/dynamic-pricing.js +18 -18
  17. package/dist/knowledge/flywheel-loop.js +11 -11
  18. package/dist/knowledge/glossary.js +22 -22
  19. package/dist/knowledge/guard-ledger.d.ts +1 -1
  20. package/dist/knowledge/guard-ledger.js +145 -104
  21. package/dist/knowledge/guard-lint.d.ts +77 -0
  22. package/dist/knowledge/guard-lint.js +670 -0
  23. package/dist/knowledge/guard-migration.d.ts +48 -0
  24. package/dist/knowledge/guard-migration.js +228 -0
  25. package/dist/knowledge/guard-puzzle.d.ts +109 -14
  26. package/dist/knowledge/guard-puzzle.js +627 -101
  27. package/dist/knowledge/guard-risk.d.ts +10 -1
  28. package/dist/knowledge/guard-risk.js +1634 -292
  29. package/dist/knowledge/guard-templates.d.ts +38 -0
  30. package/dist/knowledge/guard-templates.js +605 -0
  31. package/dist/knowledge/guard-translation.d.ts +14 -2
  32. package/dist/knowledge/guard-translation.js +825 -194
  33. package/dist/knowledge/index.d.ts +8 -4
  34. package/dist/knowledge/index.js +9 -5
  35. package/dist/knowledge/industry-evolution.js +29 -29
  36. package/dist/knowledge/industry-generalizer.js +52 -52
  37. package/dist/knowledge/industry-registry.js +20 -33
  38. package/dist/knowledge/intent-metrics.js +67 -67
  39. package/dist/knowledge/process-model.js +80 -80
  40. package/dist/knowledge/reputation-rules.js +9 -9
  41. package/dist/knowledge/reward-templates.js +51 -51
  42. package/dist/knowledge/safety-rules.js +3 -3
  43. package/dist/knowledge/tool-constraints.js +20 -4
  44. package/dist/knowledge/trust-metrics.js +26 -26
  45. package/dist/project/graph.d.ts +1 -0
  46. package/dist/project/graph.js +27 -1
  47. package/dist/project/index.d.ts +1 -0
  48. package/dist/project/index.js +39 -2
  49. package/dist/project/namespace.d.ts +11 -1
  50. package/dist/project/namespace.js +27 -2
  51. package/dist/project/query.d.ts +2 -0
  52. package/dist/project/query.js +56 -15
  53. package/dist/rules.d.ts +12 -0
  54. package/dist/rules.js +9 -0
  55. package/dist/schema/call/allocation.d.ts +10 -10
  56. package/dist/schema/call/base.js +19 -19
  57. package/dist/schema/call/bridge.d.ts +32 -32
  58. package/dist/schema/call/demand.d.ts +84 -84
  59. package/dist/schema/call/guard.d.ts +153 -0
  60. package/dist/schema/call/guard.js +50 -0
  61. package/dist/schema/call/machine.d.ts +38 -38
  62. package/dist/schema/call/permission.d.ts +78 -78
  63. package/dist/schema/call/repository.d.ts +22 -22
  64. package/dist/schema/call/semantic.js +229 -25
  65. package/dist/schema/call/service.d.ts +7 -7
  66. package/dist/schema/local/wip.d.ts +39 -19
  67. package/dist/schema/local/wip.js +5 -5
  68. package/dist/schema/messenger/index.d.ts +26 -26
  69. package/dist/schema/messenger/index.js +2 -2
  70. package/dist/schema/operations.d.ts +270 -192
  71. package/dist/schema/query/index.d.ts +184 -184
  72. package/dist/schema/query/index.js +15 -9
  73. package/dist/schema/trust/index.d.ts +4 -4
  74. package/dist/schema/utils/guard-parser.js +4 -4
  75. package/dist/schema/utils/guard-query-utils.d.ts +7 -0
  76. package/dist/schema/utils/guard-query-utils.js +14 -1
  77. package/dist/schema/utils/node-parser.js +14 -14
  78. package/dist/schemas/bridge_operation.output.json +15 -15
  79. package/dist/schemas/index.json +1 -1
  80. package/dist/schemas/messenger_operation.output.json +18 -16
  81. package/dist/schemas/onchain_events.output.json +15 -15
  82. package/dist/schemas/onchain_operations.output.json +16 -16
  83. package/dist/schemas/onchain_operations.schema.json +11 -20
  84. package/dist/schemas/onchain_operations_allocation.schema.json +7 -10
  85. package/dist/schemas/onchain_operations_machine.schema.json +2 -5
  86. package/dist/schemas/onchain_operations_service.schema.json +2 -5
  87. package/dist/schemas/onchain_table_data.output.json +20 -26
  88. package/dist/schemas/wip_file.output.json +24 -1
  89. package/dist/tools/handlers/bridge.d.ts +1 -0
  90. package/dist/tools/handlers/bridge.js +1 -0
  91. package/dist/tools/handlers/config.d.ts +2 -0
  92. package/dist/tools/handlers/config.js +71 -0
  93. package/dist/tools/handlers/file-export.d.ts +3 -0
  94. package/dist/tools/handlers/file-export.js +90 -0
  95. package/dist/tools/handlers/local.d.ts +30 -0
  96. package/dist/tools/handlers/local.js +27 -0
  97. package/dist/tools/handlers/messenger.d.ts +16 -0
  98. package/dist/tools/handlers/messenger.js +187 -0
  99. package/dist/tools/handlers/onchain.d.ts +2 -0
  100. package/dist/tools/handlers/onchain.js +246 -0
  101. package/dist/tools/handlers/project.d.ts +2 -0
  102. package/dist/tools/handlers/project.js +53 -0
  103. package/dist/tools/handlers/query.d.ts +5 -0
  104. package/dist/tools/handlers/query.js +256 -0
  105. package/dist/tools/handlers/schema-query.d.ts +2 -0
  106. package/dist/tools/handlers/schema-query.js +92 -0
  107. package/dist/tools/handlers/trust.d.ts +2 -0
  108. package/dist/tools/handlers/trust.js +194 -0
  109. package/dist/tools/handlers/wip.d.ts +2 -0
  110. package/dist/tools/handlers/wip.js +44 -0
  111. package/dist/tools/index.d.ts +13 -0
  112. package/dist/tools/index.js +479 -0
  113. package/dist/tools/rules-hook.d.ts +2 -0
  114. package/dist/tools/rules-hook.js +22 -0
  115. package/dist/tools/shared.d.ts +29 -0
  116. package/dist/tools/shared.js +130 -0
  117. package/dist/tools/types.d.ts +35 -0
  118. package/dist/tools/types.js +1 -0
  119. package/dist/tools/wrap.d.ts +6 -0
  120. package/dist/tools/wrap.js +55 -0
  121. package/package.json +19 -5
@@ -1,95 +1,95 @@
1
1
  export const REWARD_TEMPLATES = [
2
2
  {
3
3
  type: "first_order",
4
- name: "首单奖励",
5
- description: "新客户首次下单后获得奖励,降低尝试门槛,促进转化。",
6
- guardCondition: "Guard 验证: order_addressholder == 当前 claim 者, order.service == Service, order 是该 holder 的第一笔订单 (通过 Repository 查询历史)",
4
+ name: "First-order reward",
5
+ description: "New customers receive a reward after their first order, lowering the trial barrier and boosting conversion.",
6
+ guardCondition: "Guard verifies: order_address.holder == current claimer, and order.service == this Service, and order is the first order for this holder (via Repository history query)",
7
7
  amountRange: { min: "0.1WOW", max: "5WOW" },
8
8
  allocationStrategy: "fixed",
9
9
  parameters: [
10
- { name: "amount", type: "string", description: "奖励金额 ( '1WOW')", required: true },
11
- { name: "budget", type: "string", description: "总预算 ( '100WOW')", required: true },
10
+ { name: "amount", type: "string", description: "Reward amount (e.g., '1WOW')", required: true },
11
+ { name: "budget", type: "string", description: "Total budget (e.g., '100WOW')", required: true },
12
12
  ],
13
- example: "新客户下单购买摄影服务,首单获得 1 WOW 返还,降低首次尝试成本。",
13
+ example: "A new customer orders a photography service and receives 1 WOW cashback on the first order, lowering the first trial cost.",
14
14
  relevantGuardOps: ["query", "repository_read"],
15
15
  },
16
16
  {
17
17
  type: "referral",
18
- name: "裂变推荐奖励",
19
- description: "老客户推荐新客户下单后,双方各获得奖励,形成口碑传播飞轮。",
20
- guardCondition: "Guard 验证: 推荐人地址在 Repository 评价表中标记为 'referred_by', 且被推荐人的订单已完成 (Progress 到达终态)",
18
+ name: "Referral viral reward",
19
+ description: "Existing customers refer new customers to place an order; both parties receive a reward, creating a word-of-mouth flywheel.",
20
+ guardCondition: "Guard verifies: referrer address is marked as 'referred_by' in the Repository review table, and the referee's order is completed (Progress reached terminal state)",
21
21
  amountRange: { min: "0.5WOW", max: "10WOW" },
22
22
  allocationStrategy: "proportional",
23
23
  parameters: [
24
- { name: "referrer_reward", type: "string", description: "推荐人奖励 ( '2WOW')", required: true },
25
- { name: "referee_reward", type: "string", description: "被推荐人奖励 ( '1WOW')", required: true },
26
- { name: "max_referrals", type: "number", description: "每人最多推荐数 ( 10)", required: false },
24
+ { name: "referrer_reward", type: "string", description: "Referrer reward (e.g., '2WOW')", required: true },
25
+ { name: "referee_reward", type: "string", description: "Referee reward (e.g., '1WOW')", required: true },
26
+ { name: "max_referrals", type: "number", description: "Max referrals per person (e.g., 10)", required: false },
27
27
  ],
28
- example: "Alice 推荐 Bob 购买服务,Bob 完成首单后 Alice 2 WOWBob 1 WOW",
28
+ example: "Alice refers Bob to purchase a service; after Bob completes the first order, Alice gets 2 WOW and Bob gets 1 WOW.",
29
29
  relevantGuardOps: ["query", "repository_read", "repository_write"],
30
30
  },
31
31
  {
32
32
  type: "loyalty",
33
- name: "忠诚度阶梯奖励",
34
- description: "客户累计消费达到阶梯后解锁更高奖励,提升复购率和客单价。",
35
- guardCondition: "Guard 验证: 通过 Repository 查询该地址历史订单数 >= N, N 为当前阶梯阈值",
33
+ name: "Loyalty tiered reward",
34
+ description: "Customers unlock higher rewards after reaching cumulative spending tiers, improving repeat rate and average order value.",
35
+ guardCondition: "Guard verifies: via Repository query, the address's historical order count >= N, where N is the current tier threshold",
36
36
  amountRange: { min: "1WOW", max: "50WOW" },
37
37
  allocationStrategy: "tiered",
38
38
  parameters: [
39
- { name: "tier1_orders", type: "number", description: "第一阶梯订单数 ( 3)", required: true },
40
- { name: "tier1_reward", type: "string", description: "第一阶梯奖励 ( '1WOW')", required: true },
41
- { name: "tier2_orders", type: "number", description: "第二阶梯订单数 ( 10)", required: true },
42
- { name: "tier2_reward", type: "string", description: "第二阶梯奖励 ( '5WOW')", required: true },
43
- { name: "tier3_orders", type: "number", description: "第三阶梯订单数 ( 30)", required: false },
44
- { name: "tier3_reward", type: "string", description: "第三阶梯奖励 ( '20WOW')", required: false },
39
+ { name: "tier1_orders", type: "number", description: "Tier 1 order count (e.g., 3)", required: true },
40
+ { name: "tier1_reward", type: "string", description: "Tier 1 reward (e.g., '1WOW')", required: true },
41
+ { name: "tier2_orders", type: "number", description: "Tier 2 order count (e.g., 10)", required: true },
42
+ { name: "tier2_reward", type: "string", description: "Tier 2 reward (e.g., '5WOW')", required: true },
43
+ { name: "tier3_orders", type: "number", description: "Tier 3 order count (e.g., 30)", required: false },
44
+ { name: "tier3_reward", type: "string", description: "Tier 3 reward (e.g., '20WOW')", required: false },
45
45
  ],
46
- example: "客户累计 3 单得 1 WOW10 单得 5 WOW30 单得 20 WOW,激励持续消费。",
46
+ example: "A customer with 3 cumulative orders gets 1 WOW, 10 orders gets 5 WOW, 30 orders gets 20 WOW, incentivizing continued spending.",
47
47
  relevantGuardOps: ["query", "repository_read"],
48
48
  },
49
49
  {
50
50
  type: "flash_sale",
51
- name: "限时闪购",
52
- description: "在限定时间窗口内提供折扣或额外奖励,制造紧迫感促进即时转化。",
53
- guardCondition: "Guard 验证: 当前区块时间在 [start_time, end_time] 范围内 (Guard 时间条件)",
51
+ name: "Limited-time flash sale",
52
+ description: "Provides discounts or extra rewards within a limited time window, creating urgency to drive instant conversion.",
53
+ guardCondition: "Guard verifies: current block time is within [start_time, end_time] range (Guard time condition)",
54
54
  amountRange: { min: "0.1WOW", max: "20WOW" },
55
55
  allocationStrategy: "fixed",
56
56
  parameters: [
57
- { name: "start_time", type: "string", description: "开始时间 (Unix timestamp)", required: true },
58
- { name: "end_time", type: "string", description: "结束时间 (Unix timestamp)", required: true },
59
- { name: "amount", type: "string", description: "闪购奖励金额", required: true },
60
- { name: "max_claims", type: "number", description: "最大领取数 ( 100)", required: true },
57
+ { name: "start_time", type: "string", description: "Start time (Unix timestamp)", required: true },
58
+ { name: "end_time", type: "string", description: "End time (Unix timestamp)", required: true },
59
+ { name: "amount", type: "string", description: "Flash sale reward amount", required: true },
60
+ { name: "max_claims", type: "number", description: "Max claims (e.g., 100)", required: true },
61
61
  ],
62
- example: "周末限时 48 小时闪购,下单客户额外获得 2 WOW 返还,前 100 名有效。",
62
+ example: "Weekend 48-hour flash sale: ordering customers get an extra 2 WOW cashback, valid for the first 100.",
63
63
  relevantGuardOps: ["query", "time_condition"],
64
64
  },
65
65
  {
66
66
  type: "cashback",
67
- name: "消费返现",
68
- description: "客户完成订单后按消费比例返现,提升复购意愿。",
69
- guardCondition: "Guard 验证: order 已到达终态 (Progress completed), order.service == Service",
67
+ name: "Spending cashback",
68
+ description: "Customers receive cashback proportional to spending after completing an order, improving repeat purchase willingness.",
69
+ guardCondition: "Guard verifies: order has reached terminal state (Progress completed), and order.service == this Service",
70
70
  amountRange: { min: "0.1WOW", max: "100WOW" },
71
71
  allocationStrategy: "proportional",
72
72
  parameters: [
73
- { name: "cashback_rate", type: "string", description: "返现比例 ( '0.1' = 10%)", required: true },
74
- { name: "max_cashback", type: "string", description: "单笔最大返现 ( '10WOW')", required: true },
75
- { name: "budget", type: "string", description: "总预算 ( '500WOW')", required: true },
73
+ { name: "cashback_rate", type: "string", description: "Cashback rate (e.g., '0.1' = 10%)", required: true },
74
+ { name: "max_cashback", type: "string", description: "Max cashback per order (e.g., '10WOW')", required: true },
75
+ { name: "budget", type: "string", description: "Total budget (e.g., '500WOW')", required: true },
76
76
  ],
77
- example: "客户消费 10 WOW,按 10% 比例返现 1 WOW,下次消费可抵扣。",
77
+ example: "A customer spends 10 WOW, gets 10% cashback = 1 WOW, which can be deducted on the next purchase.",
78
78
  relevantGuardOps: ["query"],
79
79
  },
80
80
  {
81
81
  type: "milestone",
82
- name: "里程碑奖励",
83
- description: "Service 达到特定里程碑(如 100 单、1000 客户)时给早期支持者发放额外奖励。",
84
- guardCondition: "Guard 验证: Repository 查询 Service 累计订单数 >= milestone_threshold, claim 者为早期客户 (order_index < milestone)",
82
+ name: "Milestone reward",
83
+ description: "When a Service reaches a specific milestone (e.g., 100 orders, 1000 customers), early supporters receive extra rewards.",
84
+ guardCondition: "Guard verifies: Repository query shows Service cumulative order count >= milestone_threshold, and claimer is an early customer (order_index < milestone)",
85
85
  amountRange: { min: "1WOW", max: "100WOW" },
86
86
  allocationStrategy: "fixed",
87
87
  parameters: [
88
- { name: "milestone", type: "number", description: "里程碑值 ( 100)", required: true },
89
- { name: "reward_per_user", type: "string", description: "每人奖励 ( '5WOW')", required: true },
90
- { name: "max_recipients", type: "number", description: "最大受益人数 ( 50)", required: true },
88
+ { name: "milestone", type: "number", description: "Milestone value (e.g., 100)", required: true },
89
+ { name: "reward_per_user", type: "string", description: "Reward per person (e.g., '5WOW')", required: true },
90
+ { name: "max_recipients", type: "number", description: "Max beneficiaries (e.g., 50)", required: true },
91
91
  ],
92
- example: "Service 达到 100 单里程碑,前 50 名客户每人获得 5 WOW 额外奖励。",
92
+ example: "Service reaches the 100-order milestone; the first 50 customers each receive 5 WOW extra reward.",
93
93
  relevantGuardOps: ["query", "repository_read"],
94
94
  },
95
95
  ];
@@ -102,22 +102,22 @@ export function listRewardTemplates() {
102
102
  }
103
103
  export function suggestRewardTemplate(intent) {
104
104
  const lower = intent.toLowerCase();
105
- if (lower.includes("首单") || lower.includes("new") || lower.includes("first")) {
105
+ if (lower.includes("first order") || lower.includes("new") || lower.includes("first")) {
106
106
  return getRewardTemplate("first_order");
107
107
  }
108
- if (lower.includes("推荐") || lower.includes("裂变") || lower.includes("referral")) {
108
+ if (lower.includes("referral") || lower.includes("viral") || lower.includes("referral")) {
109
109
  return getRewardTemplate("referral");
110
110
  }
111
- if (lower.includes("复购") || lower.includes("忠诚") || lower.includes("loyalty")) {
111
+ if (lower.includes("repeat") || lower.includes("loyalty") || lower.includes("loyalty")) {
112
112
  return getRewardTemplate("loyalty");
113
113
  }
114
- if (lower.includes("限时") || lower.includes("闪购") || lower.includes("flash")) {
114
+ if (lower.includes("limited-time") || lower.includes("flash") || lower.includes("flash")) {
115
115
  return getRewardTemplate("flash_sale");
116
116
  }
117
- if (lower.includes("返现") || lower.includes("cashback")) {
117
+ if (lower.includes("cashback") || lower.includes("cashback")) {
118
118
  return getRewardTemplate("cashback");
119
119
  }
120
- if (lower.includes("里程碑") || lower.includes("milestone")) {
120
+ if (lower.includes("milestone") || lower.includes("milestone")) {
121
121
  return getRewardTemplate("milestone");
122
122
  }
123
123
  return undefined;
@@ -146,8 +146,8 @@ export const CONFIRMATION_RULES = [
146
146
  bypass_on_explicit_intent: [
147
147
  "use default account",
148
148
  "default account is fine",
149
- "用默认账户",
150
- "用默认账户即可",
149
+ "use the default account",
150
+ "default account works fine",
151
151
  ],
152
152
  },
153
153
  {
@@ -209,7 +209,7 @@ export const CONFIRMATION_RULES = [
209
209
  "gen_passport will consume gas for static testing",
210
210
  ],
211
211
  }),
212
- bypass_on_explicit_intent: ["test guard", "测试 guard", "gen passport", "生成 passport"],
212
+ bypass_on_explicit_intent: ["test guard", "testing guard", "gen passport", "generate passport"],
213
213
  },
214
214
  ];
215
215
  function extractAmount(data) {
@@ -26,8 +26,8 @@ export const TOOL_CONSTRAINTS = [
26
26
  constraints: [
27
27
  {
28
28
  field: "node.nodes",
29
- description: "Machine should have at least one node when published",
30
- severity: "warning",
29
+ description: "Machine must have at least one node when published",
30
+ severity: "error",
31
31
  check: (d) => {
32
32
  if (typeof d?.object === "string")
33
33
  return true;
@@ -61,7 +61,15 @@ export const TOOL_CONSTRAINTS = [
61
61
  },
62
62
  {
63
63
  operation_type: "order",
64
- constraints: [],
64
+ constraints: [
65
+ {
66
+ field: "object",
67
+ description: "Order requires an existing Order object reference",
68
+ severity: "error",
69
+ check: (d) => !!d?.object,
70
+ message: () => "Order requires 'object' field (Order object ID or name).",
71
+ },
72
+ ],
65
73
  },
66
74
  {
67
75
  operation_type: "reward",
@@ -118,7 +126,15 @@ export const TOOL_CONSTRAINTS = [
118
126
  },
119
127
  {
120
128
  operation_type: "progress",
121
- constraints: [],
129
+ constraints: [
130
+ {
131
+ field: "object",
132
+ description: "Progress requires an existing Progress object reference",
133
+ severity: "error",
134
+ check: (d) => !!d?.object,
135
+ message: () => "Progress requires 'object' field (Progress object ID or name).",
136
+ },
137
+ ],
122
138
  },
123
139
  ];
124
140
  const CONSTRAINT_INDEX = new Map(TOOL_CONSTRAINTS.map((c) => [c.operation_type, c]));
@@ -1,9 +1,9 @@
1
1
  export const TRUST_METRICS_VERSION = 1;
2
2
  const TRUST_LEVELS = [
3
- { min: 75, level: "trusted", label: "高信任" },
4
- { min: 50, level: "moderate", label: "中等信任" },
5
- { min: 25, level: "caution", label: "需注意" },
6
- { min: 0, level: "high_risk", label: "高风险" },
3
+ { min: 75, level: "trusted", label: "High trust" },
4
+ { min: 50, level: "moderate", label: "Moderate trust" },
5
+ { min: 25, level: "caution", label: "Needs attention" },
6
+ { min: 0, level: "high_risk", label: "High risk" },
7
7
  ];
8
8
  export function computeServiceTrustScore(metrics) {
9
9
  const breakdown = [];
@@ -11,49 +11,49 @@ export function computeServiceTrustScore(metrics) {
11
11
  const arbScore = computeArbitrationDimension(metrics);
12
12
  breakdown.push(arbScore);
13
13
  if (arbScore.score < arbScore.maxScore * 0.3) {
14
- warnings.push("仲裁信任分较低,建议检查仲裁记录");
14
+ warnings.push("Arbitration trust score is low; recommend checking arbitration records");
15
15
  }
16
16
  const reviewScore = computeReviewDimension(metrics);
17
17
  breakdown.push(reviewScore);
18
18
  if (reviewScore.score < reviewScore.maxScore * 0.3 && metrics.reviewStats) {
19
- warnings.push(`好评率较低 (${metrics.reviewStats.likes}/${metrics.reviewStats.totalReviews})`);
19
+ warnings.push(`Low like rate (${metrics.reviewStats.likes}/${metrics.reviewStats.totalReviews})`);
20
20
  }
21
21
  const fulfillmentScore = computeFulfillmentDimension(metrics);
22
22
  breakdown.push(fulfillmentScore);
23
23
  if (metrics.completedRate !== undefined && metrics.completedRate < 0.7) {
24
- warnings.push(`完成率仅 ${Math.round(metrics.completedRate * 100)}%`);
24
+ warnings.push(`Completion rate only ${Math.round(metrics.completedRate * 100)}%`);
25
25
  }
26
26
  const fundScore = computeFundDimension(metrics);
27
27
  breakdown.push(fundScore);
28
28
  if (metrics.compensationFundBalance === undefined || metrics.compensationFundBalance === 0n) {
29
- warnings.push("无赔偿金,客户权益保障不足");
29
+ warnings.push("No compensation fund; insufficient protection of customer rights");
30
30
  }
31
31
  const transparencyScore = computeTransparencyDimension(metrics);
32
32
  breakdown.push(transparencyScore);
33
33
  const totalScore = breakdown.reduce((sum, d) => sum + d.score, 0);
34
34
  const level = TRUST_LEVELS.find((l) => totalScore >= l.min)?.level ?? "high_risk";
35
- const label = TRUST_LEVELS.find((l) => totalScore >= l.min)?.label ?? "高风险";
35
+ const label = TRUST_LEVELS.find((l) => totalScore >= l.min)?.label ?? "High risk";
36
36
  const summary = buildSummary(totalScore, label, metrics, breakdown);
37
37
  return { score: totalScore, level, breakdown, summary, warnings };
38
38
  }
39
39
  function computeArbitrationDimension(metrics) {
40
40
  const maxScore = 30;
41
41
  if (metrics.arbitrationScore === undefined) {
42
- return { name: "arbitration", score: maxScore * 0.5, maxScore, description: "仲裁信任分(无数据,默认中等)", humanReadable: "仲裁记录: 无数据" };
42
+ return { name: "arbitration", score: maxScore * 0.5, maxScore, description: "Arbitration trust score (no data, default moderate)", humanReadable: "Arbitration record: no data" };
43
43
  }
44
44
  const score = Math.round((metrics.arbitrationScore / 100) * maxScore);
45
45
  return {
46
46
  name: "arbitration",
47
47
  score,
48
48
  maxScore,
49
- description: `仲裁信任分 ${metrics.arbitrationScore}/100`,
50
- humanReadable: `仲裁信任: ${metrics.arbitrationScore}/100${metrics.arbitrationCases !== undefined ? ` (${metrics.arbitrationCases} 案件)` : ""}`,
49
+ description: `Arbitration trust score ${metrics.arbitrationScore}/100`,
50
+ humanReadable: `Arbitration trust: ${metrics.arbitrationScore}/100${metrics.arbitrationCases !== undefined ? ` (${metrics.arbitrationCases} cases)` : ""}`,
51
51
  };
52
52
  }
53
53
  function computeReviewDimension(metrics) {
54
54
  const maxScore = 25;
55
55
  if (!metrics.reviewStats || metrics.reviewStats.totalReviews === 0) {
56
- return { name: "reviews", score: maxScore * 0.5, maxScore, description: "评价声誉(无评价数据)", humanReadable: "评价: 无数据" };
56
+ return { name: "reviews", score: maxScore * 0.5, maxScore, description: "Review reputation (no review data)", humanReadable: "Reviews: no data" };
57
57
  }
58
58
  const { likes, dislikes, verifiedReviews, totalReviews } = metrics.reviewStats;
59
59
  const likeRate = likes / Math.max(1, totalReviews);
@@ -63,14 +63,14 @@ function computeReviewDimension(metrics) {
63
63
  name: "reviews",
64
64
  score: Math.min(maxScore, score),
65
65
  maxScore,
66
- description: `好评率 ${Math.round(likeRate * 100)}% (${totalReviews} 条评价, ${verifiedReviews} 条带凭证)`,
67
- humanReadable: `好评率 ${Math.round(likeRate * 100)}% (${totalReviews} 评价)`,
66
+ description: `Like rate ${Math.round(likeRate * 100)}% (${totalReviews} reviews, ${verifiedReviews} verified)`,
67
+ humanReadable: `Like rate ${Math.round(likeRate * 100)}% (${totalReviews} reviews)`,
68
68
  };
69
69
  }
70
70
  function computeFulfillmentDimension(metrics) {
71
71
  const maxScore = 20;
72
72
  if (metrics.orderCount === undefined) {
73
- return { name: "fulfillment", score: maxScore * 0.5, maxScore, description: "履约记录(无订单数据)", humanReadable: "履约: 无数据" };
73
+ return { name: "fulfillment", score: maxScore * 0.5, maxScore, description: "Fulfillment record (no order data)", humanReadable: "Fulfillment: no data" };
74
74
  }
75
75
  let score = 0;
76
76
  const orderScore = Math.min(10, Math.floor(metrics.orderCount / 5));
@@ -85,14 +85,14 @@ function computeFulfillmentDimension(metrics) {
85
85
  name: "fulfillment",
86
86
  score: Math.min(maxScore, score),
87
87
  maxScore,
88
- description: `已完成 ${metrics.orderCount} 单, 完成率 ${metrics.completedRate !== undefined ? Math.round(metrics.completedRate * 100) + "%" : "未知"}`,
89
- humanReadable: `履约: ${metrics.orderCount} 单${metrics.avgCompletionTime !== undefined ? `, 平均 ${metrics.avgCompletionTime}h` : ""}`,
88
+ description: `Completed ${metrics.orderCount} orders, completion rate ${metrics.completedRate !== undefined ? Math.round(metrics.completedRate * 100) + "%" : "unknown"}`,
89
+ humanReadable: `Fulfillment: ${metrics.orderCount} orders${metrics.avgCompletionTime !== undefined ? `, avg ${metrics.avgCompletionTime}h` : ""}`,
90
90
  };
91
91
  }
92
92
  function computeFundDimension(metrics) {
93
93
  const maxScore = 15;
94
94
  if (metrics.compensationFundBalance === undefined || metrics.compensationFundBalance === 0n) {
95
- return { name: "fund_safety", score: 0, maxScore, description: "无赔偿金", humanReadable: "赔偿金: " };
95
+ return { name: "fund_safety", score: 0, maxScore, description: "No compensation fund", humanReadable: "Compensation fund: none" };
96
96
  }
97
97
  const threshold = 1000000000000n;
98
98
  const ratio = Number(metrics.compensationFundBalance * 100n / threshold) / 100;
@@ -101,8 +101,8 @@ function computeFundDimension(metrics) {
101
101
  name: "fund_safety",
102
102
  score,
103
103
  maxScore,
104
- description: `赔偿金 ${metrics.compensationFundBalance} 最小单位`,
105
- humanReadable: `赔偿金: 充足`,
104
+ description: `Compensation fund ${metrics.compensationFundBalance} smallest unit`,
105
+ humanReadable: `Compensation fund: sufficient`,
106
106
  };
107
107
  }
108
108
  function computeTransparencyDimension(metrics) {
@@ -118,12 +118,12 @@ function computeTransparencyDimension(metrics) {
118
118
  name: "transparency",
119
119
  score: Math.min(maxScore, score),
120
120
  maxScore,
121
- description: `链上事件 ${metrics.hasPublishedEvents ? "✓" : "✗"}, Machine ${metrics.hasMachineBound ? "✓" : "✗"}, Guard ${metrics.hasBuyGuard ? "✓" : "✗"}`,
122
- humanReadable: `透明度: ${["事件", "Machine", "Guard"].filter((_, i) => [metrics.hasPublishedEvents, metrics.hasMachineBound, metrics.hasBuyGuard][i]).join("+") || ""}`,
121
+ description: `On-chain events ${metrics.hasPublishedEvents ? "✓" : "✗"}, Machine ${metrics.hasMachineBound ? "✓" : "✗"}, Guard ${metrics.hasBuyGuard ? "✓" : "✗"}`,
122
+ humanReadable: `Transparency: ${["Events", "Machine", "Guard"].filter((_, i) => [metrics.hasPublishedEvents, metrics.hasMachineBound, metrics.hasBuyGuard][i]).join("+") || "none"}`,
123
123
  };
124
124
  }
125
125
  function buildSummary(score, label, metrics, breakdown) {
126
- const parts = [`信任分 ${score}/100 (${label})`];
126
+ const parts = [`Trust score ${score}/100 (${label})`];
127
127
  for (const d of breakdown) {
128
128
  parts.push(`${d.humanReadable}`);
129
129
  }
@@ -132,7 +132,7 @@ function buildSummary(score, label, metrics, breakdown) {
132
132
  export function quickTrustCheck(metrics) {
133
133
  const result = computeServiceTrustScore(metrics);
134
134
  if (result.score < 25) {
135
- return { pass: false, reason: `信任分 ${result.score}/100,高风险: ${result.warnings.join("; ")}` };
135
+ return { pass: false, reason: `Trust score ${result.score}/100, high risk: ${result.warnings.join("; ")}` };
136
136
  }
137
- return { pass: true, reason: `信任分 ${result.score}/100 (${result.level})` };
137
+ return { pass: true, reason: `Trust score ${result.score}/100 (${result.level})` };
138
138
  }
@@ -3,6 +3,7 @@ export type EdgeKind = "machine" | "order_allocators" | "arbitrations" | "compen
3
3
  export interface GraphNode {
4
4
  id: string;
5
5
  project?: string;
6
+ projects?: string[];
6
7
  type?: ProjectObjectType;
7
8
  address?: string;
8
9
  decision_contexts?: GraphDecisionContext[];
@@ -1,3 +1,13 @@
1
+ function matchesProjectFilter(nodeProject, filter) {
2
+ if (nodeProject === filter)
3
+ return true;
4
+ if (!filter.includes("_v")) {
5
+ const m = nodeProject.match(/^(.+)_v\d+$/);
6
+ if (m && m[1] === filter)
7
+ return true;
8
+ }
9
+ return false;
10
+ }
1
11
  export class ProjectGraph {
2
12
  nodes = new Map();
3
13
  edges = [];
@@ -8,12 +18,17 @@ export class ProjectGraph {
8
18
  upsertNode(node) {
9
19
  const existing = this.nodes.get(node.id);
10
20
  if (existing) {
21
+ const mergedProjects = new Set([
22
+ ...(existing.projects ?? []),
23
+ ...(node.projects ?? []),
24
+ ]);
11
25
  this.nodes.set(node.id, {
12
26
  ...existing,
13
27
  ...node,
14
28
  project: node.project ?? existing.project,
15
29
  type: node.type ?? existing.type,
16
30
  address: node.address ?? existing.address,
31
+ projects: mergedProjects.size > 0 ? Array.from(mergedProjects) : (existing.projects ?? node.projects),
17
32
  });
18
33
  return this.nodes.get(node.id);
19
34
  }
@@ -79,7 +94,18 @@ export class ProjectGraph {
79
94
  const all = Array.from(this.nodes.values());
80
95
  if (!projectPrefix)
81
96
  return all;
82
- return all.filter((n) => n.project === projectPrefix);
97
+ return all.filter((n) => {
98
+ if (n.projects && n.projects.length > 0) {
99
+ return n.projects.some((p) => matchesProjectFilter(p, projectPrefix));
100
+ }
101
+ if (!n.project)
102
+ return false;
103
+ if (n.project === projectPrefix)
104
+ return true;
105
+ if (projectPrefix.startsWith(n.project + "_v"))
106
+ return true;
107
+ return false;
108
+ });
83
109
  }
84
110
  getDependencies(id) {
85
111
  const idxs = this.outEdges.get(id);
@@ -32,6 +32,7 @@ export declare function queryProjectObjects(prefix: string): Promise<{
32
32
  name?: string;
33
33
  address?: string;
34
34
  type?: string;
35
+ version?: string;
35
36
  }[]>;
36
37
  export declare function queryShareableObjects(): Promise<{
37
38
  name?: string;
@@ -1,7 +1,8 @@
1
- import { normalizeForProject, extractProjectPrefix, TAG_PREFIX, } from "./namespace.js";
1
+ import { normalizeForProject, extractProjectPrefix, extractAllProjectVersions, TAG_PREFIX, } from "./namespace.js";
2
2
  import { ProjectGraph, extractReferences, nodeIdOf, } from "./graph.js";
3
3
  import { listProjects, listProjectObjects, listShareableObjects, traceDependencies, traceReferencedBy, prePublishCheck, findCrossProjectReferences, } from "./query.js";
4
4
  import { isEnabled as isRuntimeEnabled } from "../config/index.js";
5
+ import { LocalMark } from "@wowok/wowok";
5
6
  import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
6
7
  import { dirname, join } from "path";
7
8
  import { homedir } from "os";
@@ -11,6 +12,33 @@ export * from "./query.js";
11
12
  export function isProjectServiceEnabled() {
12
13
  return isRuntimeEnabled("project_service");
13
14
  }
15
+ function scheduleHiddenStep(sourceNodeId, sourceTags, references) {
16
+ const versionedTags = extractAllProjectVersions(sourceTags)
17
+ .filter((p) => p.version !== undefined)
18
+ .map((p) => `${TAG_PREFIX.project}${p.prefix}_${p.version}`);
19
+ if (versionedTags.length === 0 || references.length === 0)
20
+ return;
21
+ const run = async () => {
22
+ const localMark = LocalMark.Instance();
23
+ for (const ref of references) {
24
+ try {
25
+ await localMark.add_tags(ref.target, versionedTags);
26
+ }
27
+ catch {
28
+ }
29
+ }
30
+ };
31
+ if (typeof setImmediate === "function") {
32
+ setImmediate(() => {
33
+ run().catch(() => { });
34
+ });
35
+ }
36
+ else {
37
+ Promise.resolve().then(() => {
38
+ run().catch(() => { });
39
+ });
40
+ }
41
+ }
14
42
  let GRAPH_INSTANCE = null;
15
43
  let GRAPH_HYDRATED = false;
16
44
  function isAutoHydrateEnabled() {
@@ -63,12 +91,21 @@ export function observe(operation_type, data, result) {
63
91
  const project = extractProjectPrefix(tags);
64
92
  const typeTag = tags?.find((t) => t.startsWith(TAG_PREFIX.type));
65
93
  const type = typeTag?.slice(TAG_PREFIX.type.length);
66
- const node = { id: nodeId, project, type, address };
94
+ const projectEntries = extractAllProjectVersions(tags);
95
+ const projects = projectEntries.map((p) => p.version ? `${p.prefix}_${p.version}` : p.prefix);
96
+ const node = {
97
+ id: nodeId,
98
+ project,
99
+ projects: projects.length > 0 ? projects : undefined,
100
+ type,
101
+ address,
102
+ };
67
103
  graph.upsertNode(node);
68
104
  const refs = extractReferences(operation_type, data);
69
105
  for (const r of refs) {
70
106
  graph.addEdge(nodeId, r.target, r.kind);
71
107
  }
108
+ scheduleHiddenStep(nodeId, tags, refs);
72
109
  if (isRuntimeEnabled("graph_persist")) {
73
110
  try {
74
111
  saveGraph();
@@ -39,6 +39,16 @@ export interface TagInjectionOptions {
39
39
  existingTags?: string[];
40
40
  }
41
41
  export declare function buildProjectTags(opts: TagInjectionOptions): string[];
42
+ export declare function parseProjectTagValue(value: string): {
43
+ prefix: string;
44
+ version?: string;
45
+ };
46
+ export interface ProjectTagEntry {
47
+ prefix: string;
48
+ version?: string;
49
+ raw: string;
50
+ }
51
+ export declare function extractAllProjectVersions(tags: string[] | undefined): ProjectTagEntry[];
42
52
  export declare function extractProjectPrefix(tags: string[] | undefined): string | undefined;
43
53
  export interface NormalizeResult {
44
54
  data: any;
@@ -59,4 +69,4 @@ export interface NormalizeInput {
59
69
  shareable?: boolean;
60
70
  }
61
71
  export declare function normalizeForProject(input: NormalizeInput): NormalizeResult;
62
- export declare const NAMESPACE_VERSION = 1;
72
+ export declare const NAMESPACE_VERSION = 2;
@@ -101,6 +101,9 @@ export function buildProjectTags(opts) {
101
101
  const tags = new Set(opts.existingTags ?? []);
102
102
  if (opts.projectPrefix) {
103
103
  tags.add(`${TAG_PREFIX.project}${opts.projectPrefix}`);
104
+ if (opts.version) {
105
+ tags.add(`${TAG_PREFIX.project}${opts.projectPrefix}_${opts.version}`);
106
+ }
104
107
  }
105
108
  if (opts.type) {
106
109
  tags.add(`${TAG_PREFIX.type}${opts.type}`);
@@ -119,12 +122,34 @@ export function buildProjectTags(opts) {
119
122
  }
120
123
  return Array.from(tags);
121
124
  }
125
+ export function parseProjectTagValue(value) {
126
+ const m = value.match(/^(.+?)_(v\d+)$/);
127
+ if (m) {
128
+ return { prefix: m[1], version: m[2] };
129
+ }
130
+ return { prefix: value };
131
+ }
132
+ export function extractAllProjectVersions(tags) {
133
+ if (!tags)
134
+ return [];
135
+ const result = [];
136
+ for (const t of tags) {
137
+ if (!t.startsWith(TAG_PREFIX.project))
138
+ continue;
139
+ const value = t.slice(TAG_PREFIX.project.length);
140
+ const parsed = parseProjectTagValue(value);
141
+ result.push({ ...parsed, raw: t });
142
+ }
143
+ return result;
144
+ }
122
145
  export function extractProjectPrefix(tags) {
123
146
  if (!tags)
124
147
  return undefined;
125
148
  for (const t of tags) {
126
149
  if (t.startsWith(TAG_PREFIX.project)) {
127
- return t.slice(TAG_PREFIX.project.length);
150
+ const value = t.slice(TAG_PREFIX.project.length);
151
+ const parsed = parseProjectTagValue(value);
152
+ return parsed.prefix;
128
153
  }
129
154
  }
130
155
  return undefined;
@@ -178,4 +203,4 @@ export function normalizeForProject(input) {
178
203
  project: { prefix, type: inferredType, version },
179
204
  };
180
205
  }
181
- export const NAMESPACE_VERSION = 1;
206
+ export const NAMESPACE_VERSION = 2;
@@ -3,10 +3,12 @@ export interface ProjectInfo {
3
3
  prefix: string;
4
4
  objectCount: number;
5
5
  types: string[];
6
+ versions?: string[];
6
7
  objects: Array<{
7
8
  name?: string;
8
9
  address?: string;
9
10
  type?: string;
11
+ version?: string;
10
12
  }>;
11
13
  }
12
14
  export interface DependencyTrace {