@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.
- package/dist/customer/industry-risks.js +31 -31
- package/dist/customer/order-monitor.js +57 -57
- package/dist/customer/order-strategy.js +89 -89
- package/dist/customer/post-purchase.js +97 -97
- package/dist/customer/reminder-system.js +26 -26
- package/dist/customer/risk-assessment.js +46 -46
- package/dist/customer/types.d.ts +4 -4
- package/dist/customer/types.js +4 -4
- package/dist/customer/user-preferences.js +50 -50
- package/dist/experience/intent-distill.js +6 -6
- package/dist/index.d.ts +2 -2
- package/dist/index.js +11 -1624
- package/dist/knowledge/acquisition-flywheel.js +64 -64
- package/dist/knowledge/arbitration-trust.js +10 -10
- package/dist/knowledge/demand-matching.js +8 -8
- package/dist/knowledge/dynamic-pricing.js +18 -18
- package/dist/knowledge/flywheel-loop.js +11 -11
- package/dist/knowledge/glossary.js +22 -22
- package/dist/knowledge/guard-ledger.d.ts +1 -1
- package/dist/knowledge/guard-ledger.js +145 -104
- package/dist/knowledge/guard-lint.d.ts +77 -0
- package/dist/knowledge/guard-lint.js +670 -0
- package/dist/knowledge/guard-migration.d.ts +48 -0
- package/dist/knowledge/guard-migration.js +228 -0
- package/dist/knowledge/guard-puzzle.d.ts +109 -14
- package/dist/knowledge/guard-puzzle.js +627 -101
- package/dist/knowledge/guard-risk.d.ts +10 -1
- package/dist/knowledge/guard-risk.js +1634 -292
- package/dist/knowledge/guard-templates.d.ts +38 -0
- package/dist/knowledge/guard-templates.js +605 -0
- package/dist/knowledge/guard-translation.d.ts +14 -2
- package/dist/knowledge/guard-translation.js +825 -194
- package/dist/knowledge/index.d.ts +8 -4
- package/dist/knowledge/index.js +9 -5
- package/dist/knowledge/industry-evolution.js +29 -29
- package/dist/knowledge/industry-generalizer.js +52 -52
- package/dist/knowledge/industry-registry.js +20 -33
- package/dist/knowledge/intent-metrics.js +67 -67
- package/dist/knowledge/process-model.js +80 -80
- package/dist/knowledge/reputation-rules.js +9 -9
- package/dist/knowledge/reward-templates.js +51 -51
- package/dist/knowledge/safety-rules.js +3 -3
- package/dist/knowledge/tool-constraints.js +20 -4
- package/dist/knowledge/trust-metrics.js +26 -26
- package/dist/project/graph.d.ts +1 -0
- package/dist/project/graph.js +27 -1
- package/dist/project/index.d.ts +1 -0
- package/dist/project/index.js +39 -2
- package/dist/project/namespace.d.ts +11 -1
- package/dist/project/namespace.js +27 -2
- package/dist/project/query.d.ts +2 -0
- package/dist/project/query.js +56 -15
- package/dist/rules.d.ts +12 -0
- package/dist/rules.js +9 -0
- package/dist/schema/call/allocation.d.ts +10 -10
- package/dist/schema/call/base.js +19 -19
- package/dist/schema/call/bridge.d.ts +32 -32
- package/dist/schema/call/demand.d.ts +84 -84
- package/dist/schema/call/guard.d.ts +153 -0
- package/dist/schema/call/guard.js +50 -0
- package/dist/schema/call/machine.d.ts +38 -38
- package/dist/schema/call/permission.d.ts +78 -78
- package/dist/schema/call/repository.d.ts +22 -22
- package/dist/schema/call/semantic.js +229 -25
- package/dist/schema/call/service.d.ts +7 -7
- package/dist/schema/local/wip.d.ts +39 -19
- package/dist/schema/local/wip.js +5 -5
- package/dist/schema/messenger/index.d.ts +26 -26
- package/dist/schema/messenger/index.js +2 -2
- package/dist/schema/operations.d.ts +270 -192
- package/dist/schema/query/index.d.ts +184 -184
- package/dist/schema/query/index.js +15 -9
- package/dist/schema/trust/index.d.ts +4 -4
- package/dist/schema/utils/guard-parser.js +4 -4
- package/dist/schema/utils/guard-query-utils.d.ts +7 -0
- package/dist/schema/utils/guard-query-utils.js +14 -1
- package/dist/schema/utils/node-parser.js +14 -14
- package/dist/schemas/bridge_operation.output.json +15 -15
- package/dist/schemas/index.json +1 -1
- package/dist/schemas/messenger_operation.output.json +18 -16
- package/dist/schemas/onchain_events.output.json +15 -15
- package/dist/schemas/onchain_operations.output.json +16 -16
- package/dist/schemas/onchain_operations.schema.json +11 -20
- package/dist/schemas/onchain_operations_allocation.schema.json +7 -10
- package/dist/schemas/onchain_operations_machine.schema.json +2 -5
- package/dist/schemas/onchain_operations_service.schema.json +2 -5
- package/dist/schemas/onchain_table_data.output.json +20 -26
- package/dist/schemas/wip_file.output.json +24 -1
- package/dist/tools/handlers/bridge.d.ts +1 -0
- package/dist/tools/handlers/bridge.js +1 -0
- package/dist/tools/handlers/config.d.ts +2 -0
- package/dist/tools/handlers/config.js +71 -0
- package/dist/tools/handlers/file-export.d.ts +3 -0
- package/dist/tools/handlers/file-export.js +90 -0
- package/dist/tools/handlers/local.d.ts +30 -0
- package/dist/tools/handlers/local.js +27 -0
- package/dist/tools/handlers/messenger.d.ts +16 -0
- package/dist/tools/handlers/messenger.js +187 -0
- package/dist/tools/handlers/onchain.d.ts +2 -0
- package/dist/tools/handlers/onchain.js +246 -0
- package/dist/tools/handlers/project.d.ts +2 -0
- package/dist/tools/handlers/project.js +53 -0
- package/dist/tools/handlers/query.d.ts +5 -0
- package/dist/tools/handlers/query.js +256 -0
- package/dist/tools/handlers/schema-query.d.ts +2 -0
- package/dist/tools/handlers/schema-query.js +92 -0
- package/dist/tools/handlers/trust.d.ts +2 -0
- package/dist/tools/handlers/trust.js +194 -0
- package/dist/tools/handlers/wip.d.ts +2 -0
- package/dist/tools/handlers/wip.js +44 -0
- package/dist/tools/index.d.ts +13 -0
- package/dist/tools/index.js +479 -0
- package/dist/tools/rules-hook.d.ts +2 -0
- package/dist/tools/rules-hook.js +22 -0
- package/dist/tools/shared.d.ts +29 -0
- package/dist/tools/shared.js +130 -0
- package/dist/tools/types.d.ts +35 -0
- package/dist/tools/types.js +1 -0
- package/dist/tools/wrap.d.ts +6 -0
- package/dist/tools/wrap.js +55 -0
- 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
|
|
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: "
|
|
11
|
-
{ name: "budget", type: "string", description: "
|
|
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: "
|
|
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
|
|
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: "
|
|
25
|
-
{ name: "referee_reward", type: "string", description: "
|
|
26
|
-
{ name: "max_referrals", type: "number", description: "
|
|
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
|
|
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
|
|
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: "
|
|
40
|
-
{ name: "tier1_reward", type: "string", description: "
|
|
41
|
-
{ name: "tier2_orders", type: "number", description: "
|
|
42
|
-
{ name: "tier2_reward", type: "string", description: "
|
|
43
|
-
{ name: "tier3_orders", type: "number", description: "
|
|
44
|
-
{ name: "tier3_reward", type: "string", description: "
|
|
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: "
|
|
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
|
|
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: "
|
|
58
|
-
{ name: "end_time", type: "string", description: "
|
|
59
|
-
{ name: "amount", type: "string", description: "
|
|
60
|
-
{ name: "max_claims", type: "number", description: "
|
|
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: "
|
|
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
|
|
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: "
|
|
74
|
-
{ name: "max_cashback", type: "string", description: "
|
|
75
|
-
{ name: "budget", type: "string", description: "
|
|
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: "
|
|
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
|
|
84
|
-
guardCondition: "Guard
|
|
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: "
|
|
89
|
-
{ name: "reward_per_user", type: "string", description: "
|
|
90
|
-
{ name: "max_recipients", type: "number", description: "
|
|
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
|
|
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("
|
|
105
|
+
if (lower.includes("first order") || lower.includes("new") || lower.includes("first")) {
|
|
106
106
|
return getRewardTemplate("first_order");
|
|
107
107
|
}
|
|
108
|
-
if (lower.includes("
|
|
108
|
+
if (lower.includes("referral") || lower.includes("viral") || lower.includes("referral")) {
|
|
109
109
|
return getRewardTemplate("referral");
|
|
110
110
|
}
|
|
111
|
-
if (lower.includes("
|
|
111
|
+
if (lower.includes("repeat") || lower.includes("loyalty") || lower.includes("loyalty")) {
|
|
112
112
|
return getRewardTemplate("loyalty");
|
|
113
113
|
}
|
|
114
|
-
if (lower.includes("
|
|
114
|
+
if (lower.includes("limited-time") || lower.includes("flash") || lower.includes("flash")) {
|
|
115
115
|
return getRewardTemplate("flash_sale");
|
|
116
116
|
}
|
|
117
|
-
if (lower.includes("
|
|
117
|
+
if (lower.includes("cashback") || lower.includes("cashback")) {
|
|
118
118
|
return getRewardTemplate("cashback");
|
|
119
119
|
}
|
|
120
|
-
if (lower.includes("
|
|
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", "
|
|
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
|
|
30
|
-
severity: "
|
|
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(
|
|
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(
|
|
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: "
|
|
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:
|
|
50
|
-
humanReadable:
|
|
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: "
|
|
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:
|
|
67
|
-
humanReadable:
|
|
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: "
|
|
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:
|
|
89
|
-
humanReadable:
|
|
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: "
|
|
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:
|
|
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:
|
|
122
|
-
humanReadable:
|
|
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 = [
|
|
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:
|
|
135
|
+
return { pass: false, reason: `Trust score ${result.score}/100, high risk: ${result.warnings.join("; ")}` };
|
|
136
136
|
}
|
|
137
|
-
return { pass: true, reason:
|
|
137
|
+
return { pass: true, reason: `Trust score ${result.score}/100 (${result.level})` };
|
|
138
138
|
}
|
package/dist/project/graph.d.ts
CHANGED
package/dist/project/graph.js
CHANGED
|
@@ -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) =>
|
|
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);
|
package/dist/project/index.d.ts
CHANGED
package/dist/project/index.js
CHANGED
|
@@ -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
|
|
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 =
|
|
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
|
-
|
|
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 =
|
|
206
|
+
export const NAMESPACE_VERSION = 2;
|
package/dist/project/query.d.ts
CHANGED
|
@@ -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 {
|