@wowok/agent-mcp 2.6.9 → 2.7.1
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/README.md +0 -2
- package/dist/customer/risk-assessment.d.ts +5 -1
- package/dist/customer/risk-assessment.js +4 -4
- package/dist/evaluation/arbitration-game.d.ts +16 -0
- package/dist/evaluation/arbitration-game.js +48 -0
- package/dist/evaluation/builtins/demand-match.d.ts +15 -0
- package/dist/evaluation/builtins/demand-match.js +153 -0
- package/dist/evaluation/builtins/index.d.ts +3 -0
- package/dist/evaluation/builtins/index.js +10 -0
- package/dist/evaluation/builtins/service-risk.d.ts +6 -0
- package/dist/evaluation/builtins/service-risk.js +55 -0
- package/dist/evaluation/capability.d.ts +50 -0
- package/dist/evaluation/capability.js +13 -0
- package/dist/evaluation/composer.d.ts +13 -0
- package/dist/evaluation/composer.js +40 -0
- package/dist/evaluation/engine.d.ts +18 -0
- package/dist/evaluation/engine.js +175 -0
- package/dist/evaluation/extract.d.ts +30 -0
- package/dist/evaluation/extract.js +115 -0
- package/dist/evaluation/gap.d.ts +2 -0
- package/dist/evaluation/gap.js +100 -0
- package/dist/evaluation/index.d.ts +11 -0
- package/dist/evaluation/index.js +11 -0
- package/dist/evaluation/node-game.d.ts +34 -0
- package/dist/evaluation/node-game.js +57 -0
- package/dist/evaluation/region.d.ts +10 -0
- package/dist/evaluation/region.js +36 -0
- package/dist/evaluation/types.d.ts +76 -0
- package/dist/evaluation/types.js +1 -0
- package/dist/evaluation/user-injection.d.ts +6 -0
- package/dist/evaluation/user-injection.js +27 -0
- package/dist/examples/education-contact-create.json +40 -0
- package/dist/examples/freelance-contact-create.json +40 -0
- package/dist/examples/insurance-machine-create.json +1 -1
- package/dist/examples/insurance-service-allocators.json +1 -1
- package/dist/examples/machine-publish.json +1 -1
- package/dist/examples/rental-ziroom-service-create.json +1 -1
- package/dist/examples/retail-adv-guard-messenger-proof-create.json +1 -1
- package/dist/examples/retail-myshop-service-create.json +1 -1
- package/dist/examples/retail-myshop-service-customer-required.json +1 -1
- package/dist/examples/subscription-contact-create.json +40 -0
- package/dist/examples/threebody-machine-create.json +1 -1
- package/dist/examples/travel-machine-create.json +1 -1
- package/dist/examples/travel-service-create.json +1 -1
- package/dist/harness/plan.js +42 -3
- package/dist/intent/enrich.d.ts +1 -0
- package/dist/intent/enrich.js +67 -0
- package/dist/intent/index.d.ts +23 -0
- package/dist/intent/index.js +60 -0
- package/dist/intent/matcher.d.ts +2 -0
- package/dist/intent/matcher.js +81 -0
- package/dist/intent/store.d.ts +19 -0
- package/dist/intent/store.js +55 -0
- package/dist/intent/types.d.ts +33 -0
- package/dist/intent/types.js +10 -0
- package/dist/knowledge/arbitration-risk.js +1 -11
- package/dist/knowledge/contact-templates.d.ts +27 -0
- package/dist/knowledge/contact-templates.js +60 -0
- package/dist/knowledge/examples-scanner.js +21 -3
- package/dist/knowledge/fund-layer.js +8 -4
- package/dist/knowledge/industry-generalizer.js +21 -21
- package/dist/knowledge/machine-risk.js +0 -1
- package/dist/knowledge/mcp-schema-audit.d.ts +1 -1
- package/dist/knowledge/mcp-schema-audit.js +8 -4
- package/dist/knowledge/service-risk.js +38 -2
- package/dist/knowledge/service-templates.js +1 -1
- package/dist/knowledge/service-translation.js +2 -2
- package/dist/knowledge/template-registry.d.ts +1 -1
- package/dist/knowledge/template-registry.js +13 -1
- package/dist/knowledge/tools-reference.js +23 -0
- package/dist/persona/analyzer.d.ts +16 -0
- package/dist/persona/analyzer.js +66 -0
- package/dist/persona/bridge.d.ts +5 -0
- package/dist/persona/bridge.js +86 -0
- package/dist/persona/defaults.d.ts +4 -0
- package/dist/persona/defaults.js +195 -0
- package/dist/persona/experience-bridge.d.ts +3 -0
- package/dist/persona/experience-bridge.js +23 -0
- package/dist/persona/index.d.ts +18 -0
- package/dist/persona/index.js +71 -0
- package/dist/persona/model.d.ts +7 -0
- package/dist/persona/model.js +111 -0
- package/dist/persona/store.d.ts +19 -0
- package/dist/persona/store.js +62 -0
- package/dist/persona/types.d.ts +43 -0
- package/dist/persona/types.js +5 -0
- package/dist/project/handlers.d.ts +5 -0
- package/dist/project/handlers.js +23 -1
- package/dist/project/semantic-graph.js +47 -0
- package/dist/rules.d.ts +2 -0
- package/dist/rules.js +43 -0
- package/dist/schema/call/semantic.js +23 -1
- package/dist/schema/call/service.js +7 -1
- package/dist/schema/evaluation/index.d.ts +4239 -0
- package/dist/schema/evaluation/index.js +356 -0
- package/dist/schema/index.d.ts +4 -0
- package/dist/schema/index.js +4 -0
- package/dist/schema/intent-radar/index.d.ts +284 -0
- package/dist/schema/intent-radar/index.js +89 -0
- package/dist/schema/messenger/index.d.ts +171 -0
- package/dist/schema/messenger/index.js +5 -0
- package/dist/schema/operations.js +1 -1
- package/dist/schema/persona/index.d.ts +1985 -0
- package/dist/schema/persona/index.js +148 -0
- package/dist/schema/project/index.d.ts +2 -2
- package/dist/schema/query/index.js +6 -0
- package/dist/schema/sync-layer4.d.ts +1 -1
- package/dist/schema/sync-layer4.js +9 -5
- package/dist/schema/task-status.d.ts +168 -0
- package/dist/schema/task-status.js +36 -0
- package/dist/schema/trust/index.js +1 -1
- package/dist/schemas/evaluation_operation.output.json +677 -0
- package/dist/schemas/evaluation_operation.schema.json +903 -0
- package/dist/schemas/index.json +25 -1
- package/dist/schemas/intent_radar.output.json +229 -0
- package/dist/schemas/intent_radar.schema.json +135 -0
- package/dist/schemas/messenger_operation.output.json +14 -0
- package/dist/schemas/messenger_operation.schema.json +18 -0
- package/dist/schemas/onchain_operations.schema.json +2 -2
- package/dist/schemas/onchain_operations_service.schema.json +2 -2
- package/dist/schemas/persona_operation.output.json +389 -0
- package/dist/schemas/persona_operation.schema.json +247 -0
- package/dist/schemas/query_task_status.output.json +115 -0
- package/dist/schemas/query_task_status.schema.json +24 -0
- package/dist/schemas/query_toolkit.output.json +1 -1
- package/dist/schemas/trust_score.schema.json +1 -1
- package/dist/tools/handlers/evaluation.d.ts +2 -0
- package/dist/tools/handlers/evaluation.js +123 -0
- package/dist/tools/handlers/intent-radar.d.ts +2 -0
- package/dist/tools/handlers/intent-radar.js +76 -0
- package/dist/tools/handlers/onchain.js +98 -0
- package/dist/tools/handlers/persona.d.ts +4 -0
- package/dist/tools/handlers/persona.js +89 -0
- package/dist/tools/handlers/task-status.d.ts +0 -168
- package/dist/tools/handlers/task-status.js +0 -29
- package/dist/tools/index.js +83 -7
- package/dist/tools/wip-deploy-assist.d.ts +1 -1
- package/dist/tools/wip-deploy-assist.js +33 -5
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
# WoWok Agent (MCP Server)
|
|
2
2
|
Making It Easy for AI Agents to Communicate, Collaborate, Trade, and Trust.
|
|
3
3
|
|
|
4
|
-
GitHub: [https://github.com/wowok-ai/agent](https://github.com/wowok-ai/agent)
|
|
5
|
-
|
|
6
4
|
AI Skills: [https://github.com/wowok-ai/skills](https://github.com/wowok-ai/skills)
|
|
7
5
|
|
|
8
6
|
Docs: [https://github.com/wowok-ai/docs/](https://github.com/wowok-ai/docs/)
|
|
@@ -1,8 +1,12 @@
|
|
|
1
|
-
import type { InfoPuzzle, RiskScore, RiskLevel } from "./types.js";
|
|
1
|
+
import type { InfoPuzzle, RiskScore, RiskLevel, RiskDimensionScore } from "./types.js";
|
|
2
2
|
import { CUSTOMER_INTELLIGENCE_VERSION } from "./types.js";
|
|
3
3
|
export declare function riskLevelFromScore(score: number): RiskLevel;
|
|
4
4
|
export declare function riskLevelLabel(level: RiskLevel): string;
|
|
5
5
|
export declare function riskLevelEmoji(level: RiskLevel): string;
|
|
6
|
+
export declare function assessWorkflowRisk(puzzle: InfoPuzzle): RiskDimensionScore;
|
|
7
|
+
export declare function assessFundRisk(puzzle: InfoPuzzle): RiskDimensionScore;
|
|
8
|
+
export declare function assessTrustRisk(puzzle: InfoPuzzle): RiskDimensionScore;
|
|
9
|
+
export declare function assessBehaviorRisk(puzzle: InfoPuzzle): RiskDimensionScore;
|
|
6
10
|
export declare function assessRisk(puzzle: InfoPuzzle): RiskScore;
|
|
7
11
|
export declare function passesRiskThreshold(score: RiskScore, minLevel?: RiskLevel): boolean;
|
|
8
12
|
export { CUSTOMER_INTELLIGENCE_VERSION };
|
|
@@ -11,7 +11,7 @@ export function riskLevelEmoji(level) {
|
|
|
11
11
|
const entry = RISK_LEVELS.find((l) => l.level === level);
|
|
12
12
|
return entry?.color ?? "🔴";
|
|
13
13
|
}
|
|
14
|
-
function assessWorkflowRisk(puzzle) {
|
|
14
|
+
export function assessWorkflowRisk(puzzle) {
|
|
15
15
|
const wf = puzzle.workflow_analysis;
|
|
16
16
|
const checks = [];
|
|
17
17
|
const hasArb = wf?.has_arbitration_binding ?? wf?.has_arbitration_path ?? false;
|
|
@@ -68,7 +68,7 @@ function assessWorkflowRisk(puzzle) {
|
|
|
68
68
|
const score = checks.reduce((sum, c) => sum + (c.passed ? c.weight : 0), 0);
|
|
69
69
|
return { name: "workflow", score, max_score: RISK_DIMENSION_MAX.workflow, checks };
|
|
70
70
|
}
|
|
71
|
-
function assessFundRisk(puzzle) {
|
|
71
|
+
export function assessFundRisk(puzzle) {
|
|
72
72
|
const fund = puzzle.fund_safety;
|
|
73
73
|
const checks = [];
|
|
74
74
|
let compScore = 0;
|
|
@@ -130,7 +130,7 @@ function assessFundRisk(puzzle) {
|
|
|
130
130
|
: naiveScore;
|
|
131
131
|
return { name: "fund", score, max_score: RISK_DIMENSION_MAX.fund, checks };
|
|
132
132
|
}
|
|
133
|
-
function assessTrustRisk(puzzle) {
|
|
133
|
+
export function assessTrustRisk(puzzle) {
|
|
134
134
|
const trust = puzzle.trust_signals;
|
|
135
135
|
const checks = [];
|
|
136
136
|
const arbIndependent = trust?.arbitration_independent ?? true;
|
|
@@ -217,7 +217,7 @@ function assessTrustRisk(puzzle) {
|
|
|
217
217
|
const score = checks.reduce((sum, c) => sum + (c.passed ? c.weight : 0), 0);
|
|
218
218
|
return { name: "trust", score, max_score: RISK_DIMENSION_MAX.trust, checks };
|
|
219
219
|
}
|
|
220
|
-
function assessBehaviorRisk(puzzle) {
|
|
220
|
+
export function assessBehaviorRisk(puzzle) {
|
|
221
221
|
const beh = puzzle.merchant_behavior;
|
|
222
222
|
const checks = [];
|
|
223
223
|
let trendPassed = false;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { ArbStatus } from "../knowledge/arbitration-ledger.js";
|
|
2
|
+
export type ArbGamePerspective = "disputant" | "arbitrator" | "voter" | "both";
|
|
3
|
+
export interface ArbGameAction {
|
|
4
|
+
action: string;
|
|
5
|
+
favorability: number;
|
|
6
|
+
is_optimal: boolean;
|
|
7
|
+
payoff_note: string;
|
|
8
|
+
risk: "low" | "medium" | "high";
|
|
9
|
+
}
|
|
10
|
+
export interface ArbGameAdvice {
|
|
11
|
+
status: ArbStatus;
|
|
12
|
+
perspective: ArbGamePerspective;
|
|
13
|
+
actions: ArbGameAction[];
|
|
14
|
+
summary: string;
|
|
15
|
+
}
|
|
16
|
+
export declare function evaluateArbGame(status: ArbStatus, perspective: ArbGamePerspective): ArbGameAdvice;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
const GAME_MATRIX = {
|
|
2
|
+
Principal_confirming: [
|
|
3
|
+
{ action: "principal_confirm", perspective: "disputant", favorability: 80, payoff: "confirm the proposition to move to arbitrator confirmation", risk: "low" },
|
|
4
|
+
{ action: "proposition_change", perspective: "disputant", favorability: 50, payoff: "modify the proposition before confirming", risk: "medium" },
|
|
5
|
+
],
|
|
6
|
+
Arbitrator_confirming: [
|
|
7
|
+
{ action: "confirm", perspective: "arbitrator", favorability: 80, payoff: "confirm to open voting", risk: "low" },
|
|
8
|
+
{ action: "reset", perspective: "arbitrator", favorability: 30, payoff: "reset back to principal confirmation (extends the case)", risk: "high" },
|
|
9
|
+
],
|
|
10
|
+
Voting: [
|
|
11
|
+
{ action: "vote", perspective: "voter", favorability: 80, payoff: "vote before the deadline", risk: "low" },
|
|
12
|
+
],
|
|
13
|
+
Arbitrated: [
|
|
14
|
+
{ action: "objection", perspective: "disputant", favorability: 60, payoff: "object the ruling (only window)", risk: "medium" },
|
|
15
|
+
{ action: "accept", perspective: "disputant", favorability: 40, payoff: "accept and await compensation", risk: "low" },
|
|
16
|
+
],
|
|
17
|
+
Objectionable: [
|
|
18
|
+
{ action: "reset", perspective: "arbitrator", favorability: 60, payoff: "reset to re-review", risk: "medium" },
|
|
19
|
+
],
|
|
20
|
+
Finished: [
|
|
21
|
+
{ action: "arb_withdraw", perspective: "both", favorability: 80, payoff: "withdraw fees / compensation", risk: "low" },
|
|
22
|
+
],
|
|
23
|
+
Withdrawn: [
|
|
24
|
+
{ action: "done", perspective: "both", favorability: 100, payoff: "case closed", risk: "low" },
|
|
25
|
+
],
|
|
26
|
+
};
|
|
27
|
+
export function evaluateArbGame(status, perspective) {
|
|
28
|
+
const entries = GAME_MATRIX[status] ?? [];
|
|
29
|
+
const visible = entries.filter((e) => e.perspective === "both" || e.perspective === perspective);
|
|
30
|
+
const actions = visible
|
|
31
|
+
.slice()
|
|
32
|
+
.sort((a, b) => b.favorability - a.favorability)
|
|
33
|
+
.map((e, i) => ({
|
|
34
|
+
action: e.action,
|
|
35
|
+
favorability: e.favorability,
|
|
36
|
+
is_optimal: i === 0,
|
|
37
|
+
payoff_note: e.payoff,
|
|
38
|
+
risk: e.risk,
|
|
39
|
+
}));
|
|
40
|
+
return {
|
|
41
|
+
status,
|
|
42
|
+
perspective,
|
|
43
|
+
actions,
|
|
44
|
+
summary: actions.length === 0
|
|
45
|
+
? `No recommended moves for ${perspective} in status '${status}'`
|
|
46
|
+
: `Optimal for ${perspective} in '${status}': '${actions[0].action}' (${actions[0].payoff_note})`,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type CapabilityVector } from "../capability.js";
|
|
2
|
+
import { type DemandExtractInput, type ServiceExtractInput } from "../extract.js";
|
|
3
|
+
import type { EvaluationResult, UserInjection } from "../types.js";
|
|
4
|
+
export declare const DEMAND_MATCH_EVALUATION = "demand_match";
|
|
5
|
+
export declare function registerDemandMatchEvaluation(engine?: import("../engine.js").EvaluationEngine): void;
|
|
6
|
+
export interface DemandMatch {
|
|
7
|
+
service: ServiceExtractInput;
|
|
8
|
+
result: EvaluationResult;
|
|
9
|
+
}
|
|
10
|
+
export declare function matchDemandToServices(demandCap: CapabilityVector, services: ServiceExtractInput[], injection?: UserInjection, limit?: number): Promise<DemandMatch[]>;
|
|
11
|
+
export interface ServiceMatch {
|
|
12
|
+
demand: DemandExtractInput;
|
|
13
|
+
result: EvaluationResult;
|
|
14
|
+
}
|
|
15
|
+
export declare function matchServiceToDemands(serviceCap: CapabilityVector, demands: DemandExtractInput[], injection?: UserInjection, limit?: number): Promise<ServiceMatch[]>;
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { requiredCapabilities } from "../capability.js";
|
|
2
|
+
import { getEvaluationEngine } from "../engine.js";
|
|
3
|
+
import { extractDemandCapability, extractServiceCapability } from "../extract.js";
|
|
4
|
+
import { relateRegion } from "../region.js";
|
|
5
|
+
export const DEMAND_MATCH_EVALUATION = "demand_match";
|
|
6
|
+
const REGION_SCORE = {
|
|
7
|
+
exact: 100,
|
|
8
|
+
contains: 85,
|
|
9
|
+
compatible: 60,
|
|
10
|
+
overlap: 40,
|
|
11
|
+
mismatch: 0,
|
|
12
|
+
};
|
|
13
|
+
const dsCaps = {
|
|
14
|
+
id: "ds_caps",
|
|
15
|
+
description: "Extract demand + service capability vectors (either may be pre-computed or raw)",
|
|
16
|
+
evaluation_ids: [DEMAND_MATCH_EVALUATION],
|
|
17
|
+
extract: (ctx) => ({
|
|
18
|
+
demand_cap: ctx.entities.demand_cap
|
|
19
|
+
?? extractDemandCapability(ctx.entities.demand),
|
|
20
|
+
service_cap: ctx.entities.service_cap
|
|
21
|
+
?? extractServiceCapability(ctx.entities.service),
|
|
22
|
+
}),
|
|
23
|
+
};
|
|
24
|
+
const regionRule = {
|
|
25
|
+
id: "region",
|
|
26
|
+
description: "Geographic region relation between demand and service",
|
|
27
|
+
dimension: "region",
|
|
28
|
+
weight: 15,
|
|
29
|
+
evaluation_ids: [DEMAND_MATCH_EVALUATION],
|
|
30
|
+
evaluate: (ctx) => {
|
|
31
|
+
const d = ctx.facts.demand_cap;
|
|
32
|
+
const s = ctx.facts.service_cap;
|
|
33
|
+
const rel = relateRegion(d.region, s.region);
|
|
34
|
+
return { score: REGION_SCORE[rel], weight: 15, reason: `region ${rel}` };
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
const industryRule = {
|
|
38
|
+
id: "industry",
|
|
39
|
+
description: "Industry scenario match",
|
|
40
|
+
dimension: "industry",
|
|
41
|
+
weight: 20,
|
|
42
|
+
evaluation_ids: [DEMAND_MATCH_EVALUATION],
|
|
43
|
+
evaluate: (ctx) => {
|
|
44
|
+
const d = ctx.facts.demand_cap;
|
|
45
|
+
const s = ctx.facts.service_cap;
|
|
46
|
+
if (d.industry === "general" || s.industry === "general") {
|
|
47
|
+
return { score: 50, weight: 20, reason: "industry unknown (neutral)" };
|
|
48
|
+
}
|
|
49
|
+
const score = d.industry === s.industry ? 100 : 0;
|
|
50
|
+
return { score, weight: 20, reason: `${d.industry} vs ${s.industry}` };
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
const priceRule = {
|
|
54
|
+
id: "price",
|
|
55
|
+
description: "Service price within demand budget",
|
|
56
|
+
dimension: "price",
|
|
57
|
+
weight: 15,
|
|
58
|
+
evaluation_ids: [DEMAND_MATCH_EVALUATION],
|
|
59
|
+
evaluate: (ctx) => {
|
|
60
|
+
const d = ctx.facts.demand_cap;
|
|
61
|
+
const s = ctx.facts.service_cap;
|
|
62
|
+
if (d.price_max === undefined || s.price_min === undefined) {
|
|
63
|
+
return { score: 50, weight: 15, reason: "price unknown (neutral)" };
|
|
64
|
+
}
|
|
65
|
+
if (s.price_min <= d.price_max) {
|
|
66
|
+
return { score: 100, weight: 15, reason: "within budget" };
|
|
67
|
+
}
|
|
68
|
+
if (s.price_min <= (d.price_max * 110n) / 100n) {
|
|
69
|
+
return { score: 50, weight: 15, reason: "slightly over budget" };
|
|
70
|
+
}
|
|
71
|
+
return { score: 0, weight: 15, reason: "over budget" };
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
const trustRule = {
|
|
75
|
+
id: "trust",
|
|
76
|
+
description: "Service trust score",
|
|
77
|
+
dimension: "trust",
|
|
78
|
+
weight: 15,
|
|
79
|
+
evaluation_ids: [DEMAND_MATCH_EVALUATION],
|
|
80
|
+
evaluate: (ctx) => {
|
|
81
|
+
const s = ctx.facts.service_cap;
|
|
82
|
+
const t = s.trust_score;
|
|
83
|
+
const score = t >= 75 ? 100 : t >= 50 ? 60 : t >= 25 ? 30 : 0;
|
|
84
|
+
return { score, weight: 15, reason: `trust ${t}` };
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
const capabilitiesRule = {
|
|
88
|
+
id: "capabilities",
|
|
89
|
+
description: "Demand capability requirements covered by the service",
|
|
90
|
+
dimension: "capabilities",
|
|
91
|
+
weight: 30,
|
|
92
|
+
evaluation_ids: [DEMAND_MATCH_EVALUATION],
|
|
93
|
+
evaluate: (ctx) => {
|
|
94
|
+
const d = ctx.facts.demand_cap;
|
|
95
|
+
const s = ctx.facts.service_cap;
|
|
96
|
+
const required = requiredCapabilities(d.capabilities);
|
|
97
|
+
if (required.length === 0) {
|
|
98
|
+
return { score: 50, weight: 30, reason: "no capability requirement (neutral)" };
|
|
99
|
+
}
|
|
100
|
+
const matched = required.filter((k) => s.capabilities[k]);
|
|
101
|
+
return {
|
|
102
|
+
score: Math.round((matched.length / required.length) * 100),
|
|
103
|
+
weight: 30,
|
|
104
|
+
matched: matched,
|
|
105
|
+
mismatched: required.filter((k) => !s.capabilities[k]),
|
|
106
|
+
reason: `${matched.length}/${required.length} required capabilities covered`,
|
|
107
|
+
};
|
|
108
|
+
},
|
|
109
|
+
};
|
|
110
|
+
const tagsRule = {
|
|
111
|
+
id: "tags",
|
|
112
|
+
description: "Keyword/tag overlap",
|
|
113
|
+
dimension: "tags",
|
|
114
|
+
weight: 5,
|
|
115
|
+
evaluation_ids: [DEMAND_MATCH_EVALUATION],
|
|
116
|
+
evaluate: (ctx) => {
|
|
117
|
+
const d = ctx.facts.demand_cap;
|
|
118
|
+
const s = ctx.facts.service_cap;
|
|
119
|
+
const demandSet = new Set((d.keywords ?? []).map((k) => k.toLowerCase()));
|
|
120
|
+
const serviceSet = new Set([...(s.tags ?? []), ...(s.keywords ?? [])].map((k) => k.toLowerCase()));
|
|
121
|
+
if (demandSet.size === 0) {
|
|
122
|
+
return { score: 50, weight: 5, reason: "no keywords (neutral)" };
|
|
123
|
+
}
|
|
124
|
+
const overlap = [...demandSet].filter((k) => serviceSet.has(k)).length;
|
|
125
|
+
return { score: Math.round((overlap / demandSet.size) * 100), weight: 5, reason: `${overlap}/${demandSet.size} keywords` };
|
|
126
|
+
},
|
|
127
|
+
};
|
|
128
|
+
export function registerDemandMatchEvaluation(engine = getEvaluationEngine()) {
|
|
129
|
+
engine.registerDataSource(dsCaps);
|
|
130
|
+
for (const r of [regionRule, industryRule, priceRule, trustRule, capabilitiesRule, tagsRule]) {
|
|
131
|
+
engine.registerRule(r);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
export async function matchDemandToServices(demandCap, services, injection, limit = 5) {
|
|
135
|
+
const engine = getEvaluationEngine();
|
|
136
|
+
const matches = [];
|
|
137
|
+
for (const service of services) {
|
|
138
|
+
const result = await engine.evaluate(DEMAND_MATCH_EVALUATION, { demand_cap: demandCap, service }, injection);
|
|
139
|
+
matches.push({ service, result });
|
|
140
|
+
}
|
|
141
|
+
matches.sort((a, b) => b.result.total - a.result.total);
|
|
142
|
+
return matches.slice(0, limit);
|
|
143
|
+
}
|
|
144
|
+
export async function matchServiceToDemands(serviceCap, demands, injection, limit = 5) {
|
|
145
|
+
const engine = getEvaluationEngine();
|
|
146
|
+
const matches = [];
|
|
147
|
+
for (const demand of demands) {
|
|
148
|
+
const result = await engine.evaluate(DEMAND_MATCH_EVALUATION, { service_cap: serviceCap, demand }, injection);
|
|
149
|
+
matches.push({ demand, result });
|
|
150
|
+
}
|
|
151
|
+
matches.sort((a, b) => b.result.total - a.result.total);
|
|
152
|
+
return matches.slice(0, limit);
|
|
153
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export declare function registerBuiltinEvaluations(): void;
|
|
2
|
+
export { registerDemandMatchEvaluation, matchDemandToServices, matchServiceToDemands, DEMAND_MATCH_EVALUATION, type DemandMatch, type ServiceMatch, } from "./demand-match.js";
|
|
3
|
+
export { registerServiceRiskEvaluation, assessServiceRisk, SERVICE_RISK_EVALUATION, } from "./service-risk.js";
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { getEvaluationEngine } from "../engine.js";
|
|
2
|
+
import { registerDemandMatchEvaluation } from "./demand-match.js";
|
|
3
|
+
import { registerServiceRiskEvaluation } from "./service-risk.js";
|
|
4
|
+
export function registerBuiltinEvaluations() {
|
|
5
|
+
const engine = getEvaluationEngine();
|
|
6
|
+
registerDemandMatchEvaluation(engine);
|
|
7
|
+
registerServiceRiskEvaluation(engine);
|
|
8
|
+
}
|
|
9
|
+
export { registerDemandMatchEvaluation, matchDemandToServices, matchServiceToDemands, DEMAND_MATCH_EVALUATION, } from "./demand-match.js";
|
|
10
|
+
export { registerServiceRiskEvaluation, assessServiceRisk, SERVICE_RISK_EVALUATION, } from "./service-risk.js";
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type PuzzleRawData } from "../../customer/info-puzzle.js";
|
|
2
|
+
import type { PuzzleDepth } from "../../customer/types.js";
|
|
3
|
+
import type { EvaluationResult, UserInjection } from "../types.js";
|
|
4
|
+
export declare const SERVICE_RISK_EVALUATION = "service_risk";
|
|
5
|
+
export declare function registerServiceRiskEvaluation(engine?: import("../engine.js").EvaluationEngine): void;
|
|
6
|
+
export declare function assessServiceRisk(serviceId: string, raw: PuzzleRawData, injection?: UserInjection, depth?: PuzzleDepth): Promise<EvaluationResult>;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { assembleInfoPuzzle } from "../../customer/info-puzzle.js";
|
|
2
|
+
import { assessWorkflowRisk, assessFundRisk, assessTrustRisk, assessBehaviorRisk, } from "../../customer/risk-assessment.js";
|
|
3
|
+
import { getEvaluationEngine } from "../engine.js";
|
|
4
|
+
export const SERVICE_RISK_EVALUATION = "service_risk";
|
|
5
|
+
const dsPuzzle = {
|
|
6
|
+
id: "ds_puzzle",
|
|
7
|
+
description: "Assemble the service info puzzle from raw chain data",
|
|
8
|
+
evaluation_ids: [SERVICE_RISK_EVALUATION],
|
|
9
|
+
extract: (ctx) => {
|
|
10
|
+
const serviceId = ctx.entities.service_id;
|
|
11
|
+
const raw = ctx.entities.puzzle_raw;
|
|
12
|
+
const depth = ctx.entities.depth ?? "preorder";
|
|
13
|
+
return { puzzle: assembleInfoPuzzle(serviceId, raw, depth) };
|
|
14
|
+
},
|
|
15
|
+
};
|
|
16
|
+
function dimensionRule(id, dimension, weight, assess) {
|
|
17
|
+
return {
|
|
18
|
+
id,
|
|
19
|
+
description: `${dimension} risk dimension`,
|
|
20
|
+
dimension,
|
|
21
|
+
weight,
|
|
22
|
+
evaluation_ids: [SERVICE_RISK_EVALUATION],
|
|
23
|
+
evaluate: (ctx) => {
|
|
24
|
+
const puzzle = ctx.facts.puzzle;
|
|
25
|
+
const d = assess(puzzle);
|
|
26
|
+
const normalized = d.max_score > 0 ? Math.round((d.score / d.max_score) * 100) : 0;
|
|
27
|
+
const passed = d.checks.filter((c) => c.passed);
|
|
28
|
+
const failed = d.checks.filter((c) => !c.passed);
|
|
29
|
+
const critical = failed.filter((c) => c.advice?.startsWith("🔴"));
|
|
30
|
+
return {
|
|
31
|
+
score: normalized,
|
|
32
|
+
weight,
|
|
33
|
+
reason: critical.length > 0
|
|
34
|
+
? critical.map((c) => `[${d.name}] ${c.description}: ${c.advice}`).join("; ")
|
|
35
|
+
: `${d.name} ${d.score}/${d.max_score}`,
|
|
36
|
+
matched: passed.map((c) => c.id),
|
|
37
|
+
mismatched: failed.map((c) => c.id),
|
|
38
|
+
red_flag: critical.length > 0,
|
|
39
|
+
};
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
const workflowRule = dimensionRule("workflow", "workflow", 35, assessWorkflowRisk);
|
|
44
|
+
const fundRule = dimensionRule("fund", "fund", 25, assessFundRisk);
|
|
45
|
+
const trustRule = dimensionRule("trust", "trust", 20, assessTrustRisk);
|
|
46
|
+
const behaviorRule = dimensionRule("behavior", "behavior", 20, assessBehaviorRisk);
|
|
47
|
+
export function registerServiceRiskEvaluation(engine = getEvaluationEngine()) {
|
|
48
|
+
engine.registerDataSource(dsPuzzle);
|
|
49
|
+
for (const r of [workflowRule, fundRule, trustRule, behaviorRule]) {
|
|
50
|
+
engine.registerRule(r);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
export async function assessServiceRisk(serviceId, raw, injection, depth = "preorder") {
|
|
54
|
+
return getEvaluationEngine().evaluate(SERVICE_RISK_EVALUATION, { service_id: serviceId, puzzle_raw: raw, depth }, injection);
|
|
55
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { Region } from "./region.js";
|
|
2
|
+
export type IndustryScenario = "freelance" | "rental" | "education" | "travel" | "subscription" | "retail" | "general" | "custom";
|
|
3
|
+
export interface WorkflowCapabilities {
|
|
4
|
+
has_arbitration: boolean;
|
|
5
|
+
has_refund_path: boolean;
|
|
6
|
+
has_milestone_nodes: boolean;
|
|
7
|
+
has_compensation_fund: boolean;
|
|
8
|
+
has_wip_verification: boolean;
|
|
9
|
+
has_messenger: boolean;
|
|
10
|
+
has_buy_guard: boolean;
|
|
11
|
+
has_dynamic_pricing: boolean;
|
|
12
|
+
is_published: boolean;
|
|
13
|
+
is_paused: boolean;
|
|
14
|
+
}
|
|
15
|
+
export interface CapabilityVector {
|
|
16
|
+
id: string;
|
|
17
|
+
kind: "service" | "demand";
|
|
18
|
+
owner: string;
|
|
19
|
+
industry: IndustryScenario;
|
|
20
|
+
industry_confidence: number;
|
|
21
|
+
region: Region;
|
|
22
|
+
price_min?: bigint;
|
|
23
|
+
price_max?: bigint;
|
|
24
|
+
token_type: string;
|
|
25
|
+
ticket_size: "micro" | "small" | "medium" | "large";
|
|
26
|
+
trust_score: number;
|
|
27
|
+
reputation_like_ratio: number;
|
|
28
|
+
arbitration_independent: boolean;
|
|
29
|
+
merchant_history_count: number;
|
|
30
|
+
capabilities: WorkflowCapabilities;
|
|
31
|
+
tags: string[];
|
|
32
|
+
keywords: string[];
|
|
33
|
+
}
|
|
34
|
+
export interface CapabilityGap {
|
|
35
|
+
dimension: keyof WorkflowCapabilities | "industry" | "region" | "price" | "trust";
|
|
36
|
+
requirement: string;
|
|
37
|
+
provided: string;
|
|
38
|
+
status: "satisfied" | "partial" | "missing";
|
|
39
|
+
impact: "critical" | "major" | "minor";
|
|
40
|
+
suggestion: string;
|
|
41
|
+
}
|
|
42
|
+
export interface CapabilityGapReport {
|
|
43
|
+
entity_id: string;
|
|
44
|
+
satisfied: CapabilityGap[];
|
|
45
|
+
missing: CapabilityGap[];
|
|
46
|
+
coverage_score: number;
|
|
47
|
+
summary: string;
|
|
48
|
+
}
|
|
49
|
+
export declare const REQUIREMENT_CAPABILITY_KEYS: Array<keyof WorkflowCapabilities>;
|
|
50
|
+
export declare function requiredCapabilities(c: WorkflowCapabilities): Array<keyof WorkflowCapabilities>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export const REQUIREMENT_CAPABILITY_KEYS = [
|
|
2
|
+
"has_arbitration",
|
|
3
|
+
"has_refund_path",
|
|
4
|
+
"has_milestone_nodes",
|
|
5
|
+
"has_compensation_fund",
|
|
6
|
+
"has_wip_verification",
|
|
7
|
+
"has_messenger",
|
|
8
|
+
"has_buy_guard",
|
|
9
|
+
"has_dynamic_pricing",
|
|
10
|
+
];
|
|
11
|
+
export function requiredCapabilities(c) {
|
|
12
|
+
return REQUIREMENT_CAPABILITY_KEYS.filter((k) => c[k] === true);
|
|
13
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { CapabilityVector, WorkflowCapabilities } from "./capability.js";
|
|
2
|
+
export interface CompositePlan {
|
|
3
|
+
demand: string;
|
|
4
|
+
services: Array<{
|
|
5
|
+
id: string;
|
|
6
|
+
covered: Array<keyof WorkflowCapabilities>;
|
|
7
|
+
}>;
|
|
8
|
+
coverage_score: number;
|
|
9
|
+
remaining_missing: Array<keyof WorkflowCapabilities>;
|
|
10
|
+
feasibility: "ready" | "needs_supply_chain" | "infeasible";
|
|
11
|
+
summary: string;
|
|
12
|
+
}
|
|
13
|
+
export declare function composeServicesForDemand(demand: CapabilityVector, services: CapabilityVector[]): CompositePlan;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { requiredCapabilities } from "./capability.js";
|
|
2
|
+
import { relateRegion } from "./region.js";
|
|
3
|
+
export function composeServicesForDemand(demand, services) {
|
|
4
|
+
const required = requiredCapabilities(demand.capabilities);
|
|
5
|
+
const remaining = new Set(required);
|
|
6
|
+
const chosen = [];
|
|
7
|
+
const candidates = services.filter((s) => relateRegion(demand.region, s.region) !== "mismatch");
|
|
8
|
+
while (remaining.size > 0) {
|
|
9
|
+
let best = null;
|
|
10
|
+
for (const s of candidates) {
|
|
11
|
+
if (chosen.some((c) => c.id === s.id))
|
|
12
|
+
continue;
|
|
13
|
+
const covered = required.filter((k) => remaining.has(k) && s.capabilities[k]);
|
|
14
|
+
if (!best || covered.length > best.covered.length) {
|
|
15
|
+
best = { id: s.id, covered };
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
if (!best || best.covered.length === 0)
|
|
19
|
+
break;
|
|
20
|
+
chosen.push(best);
|
|
21
|
+
for (const k of best.covered)
|
|
22
|
+
remaining.delete(k);
|
|
23
|
+
}
|
|
24
|
+
const coverage = required.length === 0
|
|
25
|
+
? 100
|
|
26
|
+
: Math.round(((required.length - remaining.size) / required.length) * 100);
|
|
27
|
+
const feasibility = remaining.size === 0 ? "ready"
|
|
28
|
+
: chosen.length > 0 ? "needs_supply_chain"
|
|
29
|
+
: "infeasible";
|
|
30
|
+
return {
|
|
31
|
+
demand: demand.id,
|
|
32
|
+
services: chosen,
|
|
33
|
+
coverage_score: coverage,
|
|
34
|
+
remaining_missing: [...remaining],
|
|
35
|
+
feasibility,
|
|
36
|
+
summary: remaining.size === 0
|
|
37
|
+
? `Composite of ${chosen.length} service(s) covers all ${required.length} requirements`
|
|
38
|
+
: `Composite of ${chosen.length} service(s) covers ${coverage}/100; missing: ${[...remaining].join(", ") || "none"}`,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { DataSource, EvaluationLevel, EvaluationResult, EvaluationRule, UserInjection } from "./types.js";
|
|
2
|
+
export declare function levelFromScore(score: number): EvaluationLevel;
|
|
3
|
+
export declare class EvaluationEngine {
|
|
4
|
+
private static instance;
|
|
5
|
+
private dataSources;
|
|
6
|
+
private rules;
|
|
7
|
+
static Instance(): EvaluationEngine;
|
|
8
|
+
registerDataSource(ds: DataSource): boolean;
|
|
9
|
+
unregisterDataSource(id: string): boolean;
|
|
10
|
+
registerRule(rule: EvaluationRule): boolean;
|
|
11
|
+
unregisterRule(id: string): boolean;
|
|
12
|
+
getRule(id: string): EvaluationRule | undefined;
|
|
13
|
+
listRules(): EvaluationRule[];
|
|
14
|
+
getDataSource(id: string): DataSource | undefined;
|
|
15
|
+
listDataSources(): DataSource[];
|
|
16
|
+
evaluate(evaluationId: string, entities: Record<string, unknown>, injection?: UserInjection): Promise<EvaluationResult>;
|
|
17
|
+
}
|
|
18
|
+
export declare function getEvaluationEngine(): EvaluationEngine;
|