@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.
Files changed (139) hide show
  1. package/README.md +0 -2
  2. package/dist/customer/risk-assessment.d.ts +5 -1
  3. package/dist/customer/risk-assessment.js +4 -4
  4. package/dist/evaluation/arbitration-game.d.ts +16 -0
  5. package/dist/evaluation/arbitration-game.js +48 -0
  6. package/dist/evaluation/builtins/demand-match.d.ts +15 -0
  7. package/dist/evaluation/builtins/demand-match.js +153 -0
  8. package/dist/evaluation/builtins/index.d.ts +3 -0
  9. package/dist/evaluation/builtins/index.js +10 -0
  10. package/dist/evaluation/builtins/service-risk.d.ts +6 -0
  11. package/dist/evaluation/builtins/service-risk.js +55 -0
  12. package/dist/evaluation/capability.d.ts +50 -0
  13. package/dist/evaluation/capability.js +13 -0
  14. package/dist/evaluation/composer.d.ts +13 -0
  15. package/dist/evaluation/composer.js +40 -0
  16. package/dist/evaluation/engine.d.ts +18 -0
  17. package/dist/evaluation/engine.js +175 -0
  18. package/dist/evaluation/extract.d.ts +30 -0
  19. package/dist/evaluation/extract.js +115 -0
  20. package/dist/evaluation/gap.d.ts +2 -0
  21. package/dist/evaluation/gap.js +100 -0
  22. package/dist/evaluation/index.d.ts +11 -0
  23. package/dist/evaluation/index.js +11 -0
  24. package/dist/evaluation/node-game.d.ts +34 -0
  25. package/dist/evaluation/node-game.js +57 -0
  26. package/dist/evaluation/region.d.ts +10 -0
  27. package/dist/evaluation/region.js +36 -0
  28. package/dist/evaluation/types.d.ts +76 -0
  29. package/dist/evaluation/types.js +1 -0
  30. package/dist/evaluation/user-injection.d.ts +6 -0
  31. package/dist/evaluation/user-injection.js +27 -0
  32. package/dist/examples/education-contact-create.json +40 -0
  33. package/dist/examples/freelance-contact-create.json +40 -0
  34. package/dist/examples/insurance-machine-create.json +1 -1
  35. package/dist/examples/insurance-service-allocators.json +1 -1
  36. package/dist/examples/machine-publish.json +1 -1
  37. package/dist/examples/rental-ziroom-service-create.json +1 -1
  38. package/dist/examples/retail-adv-guard-messenger-proof-create.json +1 -1
  39. package/dist/examples/retail-myshop-service-create.json +1 -1
  40. package/dist/examples/retail-myshop-service-customer-required.json +1 -1
  41. package/dist/examples/subscription-contact-create.json +40 -0
  42. package/dist/examples/threebody-machine-create.json +1 -1
  43. package/dist/examples/travel-machine-create.json +1 -1
  44. package/dist/examples/travel-service-create.json +1 -1
  45. package/dist/harness/plan.js +42 -3
  46. package/dist/intent/enrich.d.ts +1 -0
  47. package/dist/intent/enrich.js +67 -0
  48. package/dist/intent/index.d.ts +23 -0
  49. package/dist/intent/index.js +60 -0
  50. package/dist/intent/matcher.d.ts +2 -0
  51. package/dist/intent/matcher.js +81 -0
  52. package/dist/intent/store.d.ts +19 -0
  53. package/dist/intent/store.js +55 -0
  54. package/dist/intent/types.d.ts +33 -0
  55. package/dist/intent/types.js +10 -0
  56. package/dist/knowledge/arbitration-risk.js +1 -11
  57. package/dist/knowledge/contact-templates.d.ts +27 -0
  58. package/dist/knowledge/contact-templates.js +60 -0
  59. package/dist/knowledge/examples-scanner.js +21 -3
  60. package/dist/knowledge/fund-layer.js +8 -4
  61. package/dist/knowledge/industry-generalizer.js +21 -21
  62. package/dist/knowledge/machine-risk.js +0 -1
  63. package/dist/knowledge/mcp-schema-audit.d.ts +1 -1
  64. package/dist/knowledge/mcp-schema-audit.js +8 -4
  65. package/dist/knowledge/service-risk.js +38 -2
  66. package/dist/knowledge/service-templates.js +1 -1
  67. package/dist/knowledge/service-translation.js +2 -2
  68. package/dist/knowledge/template-registry.d.ts +1 -1
  69. package/dist/knowledge/template-registry.js +13 -1
  70. package/dist/knowledge/tools-reference.js +23 -0
  71. package/dist/persona/analyzer.d.ts +16 -0
  72. package/dist/persona/analyzer.js +66 -0
  73. package/dist/persona/bridge.d.ts +5 -0
  74. package/dist/persona/bridge.js +86 -0
  75. package/dist/persona/defaults.d.ts +4 -0
  76. package/dist/persona/defaults.js +195 -0
  77. package/dist/persona/experience-bridge.d.ts +3 -0
  78. package/dist/persona/experience-bridge.js +23 -0
  79. package/dist/persona/index.d.ts +18 -0
  80. package/dist/persona/index.js +71 -0
  81. package/dist/persona/model.d.ts +7 -0
  82. package/dist/persona/model.js +111 -0
  83. package/dist/persona/store.d.ts +19 -0
  84. package/dist/persona/store.js +62 -0
  85. package/dist/persona/types.d.ts +43 -0
  86. package/dist/persona/types.js +5 -0
  87. package/dist/project/handlers.d.ts +5 -0
  88. package/dist/project/handlers.js +23 -1
  89. package/dist/project/semantic-graph.js +47 -0
  90. package/dist/rules.d.ts +2 -0
  91. package/dist/rules.js +43 -0
  92. package/dist/schema/call/semantic.js +23 -1
  93. package/dist/schema/call/service.js +7 -1
  94. package/dist/schema/evaluation/index.d.ts +4239 -0
  95. package/dist/schema/evaluation/index.js +356 -0
  96. package/dist/schema/index.d.ts +4 -0
  97. package/dist/schema/index.js +4 -0
  98. package/dist/schema/intent-radar/index.d.ts +284 -0
  99. package/dist/schema/intent-radar/index.js +89 -0
  100. package/dist/schema/messenger/index.d.ts +171 -0
  101. package/dist/schema/messenger/index.js +5 -0
  102. package/dist/schema/operations.js +1 -1
  103. package/dist/schema/persona/index.d.ts +1985 -0
  104. package/dist/schema/persona/index.js +148 -0
  105. package/dist/schema/project/index.d.ts +2 -2
  106. package/dist/schema/query/index.js +6 -0
  107. package/dist/schema/sync-layer4.d.ts +1 -1
  108. package/dist/schema/sync-layer4.js +9 -5
  109. package/dist/schema/task-status.d.ts +168 -0
  110. package/dist/schema/task-status.js +36 -0
  111. package/dist/schema/trust/index.js +1 -1
  112. package/dist/schemas/evaluation_operation.output.json +677 -0
  113. package/dist/schemas/evaluation_operation.schema.json +903 -0
  114. package/dist/schemas/index.json +25 -1
  115. package/dist/schemas/intent_radar.output.json +229 -0
  116. package/dist/schemas/intent_radar.schema.json +135 -0
  117. package/dist/schemas/messenger_operation.output.json +14 -0
  118. package/dist/schemas/messenger_operation.schema.json +18 -0
  119. package/dist/schemas/onchain_operations.schema.json +2 -2
  120. package/dist/schemas/onchain_operations_service.schema.json +2 -2
  121. package/dist/schemas/persona_operation.output.json +389 -0
  122. package/dist/schemas/persona_operation.schema.json +247 -0
  123. package/dist/schemas/query_task_status.output.json +115 -0
  124. package/dist/schemas/query_task_status.schema.json +24 -0
  125. package/dist/schemas/query_toolkit.output.json +1 -1
  126. package/dist/schemas/trust_score.schema.json +1 -1
  127. package/dist/tools/handlers/evaluation.d.ts +2 -0
  128. package/dist/tools/handlers/evaluation.js +123 -0
  129. package/dist/tools/handlers/intent-radar.d.ts +2 -0
  130. package/dist/tools/handlers/intent-radar.js +76 -0
  131. package/dist/tools/handlers/onchain.js +98 -0
  132. package/dist/tools/handlers/persona.d.ts +4 -0
  133. package/dist/tools/handlers/persona.js +89 -0
  134. package/dist/tools/handlers/task-status.d.ts +0 -168
  135. package/dist/tools/handlers/task-status.js +0 -29
  136. package/dist/tools/index.js +83 -7
  137. package/dist/tools/wip-deploy-assist.d.ts +1 -1
  138. package/dist/tools/wip-deploy-assist.js +33 -5
  139. package/package.json +2 -2
@@ -0,0 +1,175 @@
1
+ import { REQUIREMENT_PASS_THRESHOLD, effectiveWeight, isDataSourceEnabled, isRuleEnabled, normalizeInjection, } from "./user-injection.js";
2
+ const LEVELS = [
3
+ { min: 85, level: "low" },
4
+ { min: 70, level: "medium_low" },
5
+ { min: 50, level: "medium_high" },
6
+ { min: 0, level: "high" },
7
+ ];
8
+ export function levelFromScore(score) {
9
+ for (const l of LEVELS) {
10
+ if (score >= l.min)
11
+ return l.level;
12
+ }
13
+ return "high";
14
+ }
15
+ function appliesTo(ids, evaluationId) {
16
+ if (!ids || ids.length === 0)
17
+ return true;
18
+ return ids.includes(evaluationId);
19
+ }
20
+ export class EvaluationEngine {
21
+ static instance = null;
22
+ dataSources = new Map();
23
+ rules = new Map();
24
+ static Instance() {
25
+ if (!EvaluationEngine.instance) {
26
+ EvaluationEngine.instance = new EvaluationEngine();
27
+ }
28
+ return EvaluationEngine.instance;
29
+ }
30
+ registerDataSource(ds) {
31
+ if (!ds.id || this.dataSources.has(ds.id))
32
+ return false;
33
+ this.dataSources.set(ds.id, ds);
34
+ return true;
35
+ }
36
+ unregisterDataSource(id) {
37
+ return this.dataSources.delete(id);
38
+ }
39
+ registerRule(rule) {
40
+ if (!rule.id || this.rules.has(rule.id))
41
+ return false;
42
+ this.rules.set(rule.id, rule);
43
+ return true;
44
+ }
45
+ unregisterRule(id) {
46
+ return this.rules.delete(id);
47
+ }
48
+ getRule(id) {
49
+ return this.rules.get(id);
50
+ }
51
+ listRules() {
52
+ return Array.from(this.rules.values());
53
+ }
54
+ getDataSource(id) {
55
+ return this.dataSources.get(id);
56
+ }
57
+ listDataSources() {
58
+ return Array.from(this.dataSources.values());
59
+ }
60
+ async evaluate(evaluationId, entities, injection) {
61
+ const inj = normalizeInjection(injection);
62
+ const ctx = {
63
+ evaluation_id: evaluationId,
64
+ entities,
65
+ facts: {},
66
+ injection: inj,
67
+ now: Date.now(),
68
+ };
69
+ const trace = [];
70
+ for (const ds of this.dataSources.values()) {
71
+ if (!appliesTo(ds.evaluation_ids, evaluationId))
72
+ continue;
73
+ if (!isDataSourceEnabled(ds.id, inj)) {
74
+ trace.push({ kind: "override", id: ds.id, detail: "data source disabled by user override" });
75
+ continue;
76
+ }
77
+ if (ds.isEnabled && !ds.isEnabled(ctx))
78
+ continue;
79
+ const extracted = await ds.extract(ctx);
80
+ Object.assign(ctx.facts, extracted);
81
+ trace.push({
82
+ kind: "data_source",
83
+ id: ds.id,
84
+ detail: `extracted ${Object.keys(extracted).length} fact(s)`,
85
+ });
86
+ }
87
+ const breakdown = [];
88
+ const redFlags = [];
89
+ for (const rule of this.rules.values()) {
90
+ if (!appliesTo(rule.evaluation_ids, evaluationId))
91
+ continue;
92
+ if (!isRuleEnabled(rule.id, inj)) {
93
+ trace.push({ kind: "override", id: rule.id, detail: "rule disabled by user override" });
94
+ continue;
95
+ }
96
+ if (rule.isEnabled && !rule.isEnabled(ctx))
97
+ continue;
98
+ const contribution = rule.evaluate(ctx);
99
+ if (!contribution)
100
+ continue;
101
+ const weight = effectiveWeight(rule, inj);
102
+ breakdown.push({
103
+ rule_id: rule.id,
104
+ dimension: rule.dimension,
105
+ score: contribution.score,
106
+ weight,
107
+ reason: contribution.reason,
108
+ matched: contribution.matched,
109
+ mismatched: contribution.mismatched,
110
+ red_flag: contribution.red_flag,
111
+ });
112
+ if (contribution.red_flag) {
113
+ redFlags.push(contribution.reason ?? `${rule.id} triggered a hard block`);
114
+ }
115
+ trace.push({ kind: "rule", id: rule.id, detail: `score=${contribution.score} weight=${weight}` });
116
+ }
117
+ const total = aggregateScore(breakdown);
118
+ let blocked = redFlags.length > 0;
119
+ for (const req of inj.requirements ?? []) {
120
+ const item = breakdown.find((b) => b.rule_id === req.rule_id);
121
+ if (req.condition === "require") {
122
+ if (!item || item.score < REQUIREMENT_PASS_THRESHOLD || item.red_flag) {
123
+ blocked = true;
124
+ redFlags.push(req.note ?? `Requirement requires rule '${req.rule_id}' to pass`);
125
+ }
126
+ }
127
+ else if (req.condition === "forbid") {
128
+ if (item && item.red_flag) {
129
+ blocked = true;
130
+ redFlags.push(req.note ?? `Requirement forbids rule '${req.rule_id}' from triggering`);
131
+ }
132
+ }
133
+ }
134
+ const summary = buildSummary(evaluationId, total, breakdown, redFlags, blocked);
135
+ return {
136
+ evaluation_id: evaluationId,
137
+ total,
138
+ level: levelFromScore(total),
139
+ breakdown,
140
+ red_flags: redFlags,
141
+ blocked,
142
+ trace,
143
+ summary,
144
+ };
145
+ }
146
+ }
147
+ function aggregateScore(breakdown) {
148
+ if (breakdown.length === 0)
149
+ return 0;
150
+ let weighted = 0;
151
+ let weightSum = 0;
152
+ for (const b of breakdown) {
153
+ weighted += b.score * b.weight;
154
+ weightSum += b.weight;
155
+ }
156
+ if (weightSum <= 0)
157
+ return 0;
158
+ return clamp(Math.round(weighted / weightSum), 0, 100);
159
+ }
160
+ function clamp(n, min, max) {
161
+ return Math.max(min, Math.min(max, n));
162
+ }
163
+ function buildSummary(evaluationId, total, breakdown, redFlags, blocked) {
164
+ const parts = [`Evaluation '${evaluationId}': score ${total}/100`];
165
+ if (blocked) {
166
+ parts.push(`BLOCKED (${redFlags.length} red flag(s))`);
167
+ }
168
+ else {
169
+ parts.push(`${breakdown.length} rule(s) evaluated`);
170
+ }
171
+ return parts.join(" — ");
172
+ }
173
+ export function getEvaluationEngine() {
174
+ return EvaluationEngine.Instance();
175
+ }
@@ -0,0 +1,30 @@
1
+ import type { CapabilityVector } from "./capability.js";
2
+ export interface ServiceExtractInput {
3
+ object: string;
4
+ description: string;
5
+ location: string;
6
+ sales?: Array<{
7
+ name?: string;
8
+ price: number | bigint | string;
9
+ wip_hash?: string;
10
+ }>;
11
+ arbitrations?: string[];
12
+ compensation_fund?: number | bigint | string;
13
+ buy_guard?: string | null;
14
+ machine?: string | null;
15
+ um?: string | null;
16
+ bPublished?: boolean;
17
+ bPaused?: boolean;
18
+ order_allocators?: unknown;
19
+ owner?: string;
20
+ }
21
+ export interface DemandExtractInput {
22
+ object: string;
23
+ description: string;
24
+ location: string;
25
+ rewards?: string[];
26
+ um?: string | null;
27
+ owner?: string;
28
+ }
29
+ export declare function extractServiceCapability(input: ServiceExtractInput, overrides?: Partial<CapabilityVector>): CapabilityVector;
30
+ export declare function extractDemandCapability(input: DemandExtractInput, overrides?: Partial<CapabilityVector>): CapabilityVector;
@@ -0,0 +1,115 @@
1
+ import { parseRegion } from "./region.js";
2
+ import { findSimilarIndustries, inferTraitsFromDescription } from "../knowledge/industry-generalizer.js";
3
+ const BUILTIN_SCENARIOS = [
4
+ "freelance", "rental", "education", "travel", "subscription", "retail",
5
+ ];
6
+ function enrichFromDescription(description) {
7
+ const text = description?.trim();
8
+ if (!text) {
9
+ return { industry: "general", industry_confidence: 0, tags: [], keywords: [] };
10
+ }
11
+ const { traits, confidence, matched_keywords } = inferTraitsFromDescription(text);
12
+ const similar = findSimilarIndustries(traits, 3);
13
+ const top = similar[0];
14
+ const industry = top && BUILTIN_SCENARIOS.includes(top.industry)
15
+ ? top.industry
16
+ : "general";
17
+ const hasSignal = matched_keywords.length > 0 || (top?.similarity ?? 0) > 0.2;
18
+ return {
19
+ industry: hasSignal ? industry : "general",
20
+ industry_confidence: hasSignal ? Math.max(confidence, top?.similarity ?? 0) : 0,
21
+ tags: hasSignal ? similar.slice(0, 3).map((s) => s.industry) : [],
22
+ keywords: matched_keywords,
23
+ };
24
+ }
25
+ export function extractServiceCapability(input, overrides) {
26
+ const sales = input.sales ?? [];
27
+ const prices = sales
28
+ .map((s) => toBigInt(s.price))
29
+ .filter((p) => p !== undefined);
30
+ const arbitrations = input.arbitrations ?? [];
31
+ const compensation = toBigInt(input.compensation_fund) ?? 0n;
32
+ const enriched = enrichFromDescription(input.description);
33
+ const capabilities = {
34
+ has_arbitration: arbitrations.length > 0,
35
+ has_refund_path: arbitrations.length > 0 && compensation > 0n,
36
+ has_milestone_nodes: false,
37
+ has_compensation_fund: compensation > 0n,
38
+ has_wip_verification: sales.some((s) => !!s.wip_hash),
39
+ has_messenger: input.um != null,
40
+ has_buy_guard: input.buy_guard != null,
41
+ has_dynamic_pricing: false,
42
+ is_published: input.bPublished === true,
43
+ is_paused: input.bPaused === true,
44
+ };
45
+ const base = {
46
+ id: input.object,
47
+ kind: "service",
48
+ owner: input.owner ?? "",
49
+ industry: enriched.industry,
50
+ industry_confidence: enriched.industry_confidence,
51
+ region: parseRegion(input.location),
52
+ price_min: prices.length > 0 ? minBigInt(prices) : undefined,
53
+ price_max: prices.length > 0 ? maxBigInt(prices) : undefined,
54
+ token_type: "",
55
+ ticket_size: "medium",
56
+ trust_score: 50,
57
+ reputation_like_ratio: 1,
58
+ arbitration_independent: false,
59
+ merchant_history_count: 0,
60
+ capabilities,
61
+ tags: enriched.tags,
62
+ keywords: enriched.keywords,
63
+ };
64
+ return { ...base, ...overrides };
65
+ }
66
+ export function extractDemandCapability(input, overrides) {
67
+ const enriched = enrichFromDescription(input.description);
68
+ const base = {
69
+ id: input.object,
70
+ kind: "demand",
71
+ owner: input.owner ?? "",
72
+ industry: enriched.industry,
73
+ industry_confidence: enriched.industry_confidence,
74
+ region: parseRegion(input.location),
75
+ price_min: undefined,
76
+ price_max: undefined,
77
+ token_type: "",
78
+ ticket_size: "medium",
79
+ trust_score: 50,
80
+ reputation_like_ratio: 1,
81
+ arbitration_independent: false,
82
+ merchant_history_count: 0,
83
+ capabilities: {
84
+ has_arbitration: false,
85
+ has_refund_path: false,
86
+ has_milestone_nodes: false,
87
+ has_compensation_fund: false,
88
+ has_wip_verification: false,
89
+ has_messenger: input.um != null,
90
+ has_buy_guard: false,
91
+ has_dynamic_pricing: false,
92
+ is_published: true,
93
+ is_paused: false,
94
+ },
95
+ tags: enriched.tags,
96
+ keywords: enriched.keywords,
97
+ };
98
+ return { ...base, ...overrides };
99
+ }
100
+ function toBigInt(v) {
101
+ if (v === undefined || v === null)
102
+ return undefined;
103
+ try {
104
+ return BigInt(v);
105
+ }
106
+ catch {
107
+ return undefined;
108
+ }
109
+ }
110
+ function minBigInt(values) {
111
+ return values.reduce((a, b) => (a < b ? a : b));
112
+ }
113
+ function maxBigInt(values) {
114
+ return values.reduce((a, b) => (a > b ? a : b));
115
+ }
@@ -0,0 +1,2 @@
1
+ import type { CapabilityGapReport, CapabilityVector } from "./capability.js";
2
+ export declare function summarizeCapabilityGaps(demand: CapabilityVector, service: CapabilityVector): CapabilityGapReport;
@@ -0,0 +1,100 @@
1
+ import { requiredCapabilities } from "./capability.js";
2
+ import { relateRegion } from "./region.js";
3
+ const IMPACT = {
4
+ has_arbitration: "critical",
5
+ has_refund_path: "critical",
6
+ has_compensation_fund: "major",
7
+ has_wip_verification: "major",
8
+ has_milestone_nodes: "minor",
9
+ has_messenger: "minor",
10
+ has_buy_guard: "minor",
11
+ has_dynamic_pricing: "minor",
12
+ };
13
+ const SUGGEST = {
14
+ has_arbitration: "bind an independent Arbitration object to the Service",
15
+ has_refund_path: "configure a refund path (Arbitration + compensation_fund, or a refund Allocator)",
16
+ has_compensation_fund: "deposit compensation_fund to cover the order amount",
17
+ has_wip_verification: "set a wip_hash on the sale to prevent tampering",
18
+ has_milestone_nodes: "add milestone nodes to the Machine workflow",
19
+ has_messenger: "bind a Contact (um) to enable Messenger",
20
+ has_buy_guard: "configure a buy_guard for purchase eligibility",
21
+ has_dynamic_pricing: "configure discount/dynamic pricing",
22
+ };
23
+ export function summarizeCapabilityGaps(demand, service) {
24
+ const satisfied = [];
25
+ const missing = [];
26
+ for (const k of requiredCapabilities(demand.capabilities)) {
27
+ const ok = service.capabilities[k];
28
+ const gap = {
29
+ dimension: k,
30
+ requirement: `requires ${k}`,
31
+ provided: ok ? "provided" : "missing",
32
+ status: ok ? "satisfied" : "missing",
33
+ impact: ok ? "minor" : (IMPACT[k] ?? "minor"),
34
+ suggestion: ok ? "" : (SUGGEST[k] ?? ""),
35
+ };
36
+ (ok ? satisfied : missing).push(gap);
37
+ }
38
+ if (demand.industry !== "general" && demand.industry !== service.industry) {
39
+ missing.push({
40
+ dimension: "industry",
41
+ requirement: demand.industry,
42
+ provided: service.industry,
43
+ status: "missing",
44
+ impact: "major",
45
+ suggestion: `switch to a service in the '${demand.industry}' industry`,
46
+ });
47
+ }
48
+ const rel = relateRegion(demand.region, service.region);
49
+ if (rel === "mismatch") {
50
+ missing.push({
51
+ dimension: "region",
52
+ requirement: demand.region.raw,
53
+ provided: service.region.raw,
54
+ status: "missing",
55
+ impact: "critical",
56
+ suggestion: "choose a service in a compatible region",
57
+ });
58
+ }
59
+ else if (rel === "overlap") {
60
+ missing.push({
61
+ dimension: "region",
62
+ requirement: demand.region.raw,
63
+ provided: service.region.raw,
64
+ status: "partial",
65
+ impact: "minor",
66
+ suggestion: "different city in the same province",
67
+ });
68
+ }
69
+ if (demand.price_max !== undefined && service.price_min !== undefined && service.price_min > demand.price_max) {
70
+ missing.push({
71
+ dimension: "price",
72
+ requirement: `≤ ${demand.price_max}`,
73
+ provided: `${service.price_min}`,
74
+ status: "missing",
75
+ impact: "major",
76
+ suggestion: "negotiate a lower price or raise the budget",
77
+ });
78
+ }
79
+ if (service.trust_score < demand.trust_score) {
80
+ missing.push({
81
+ dimension: "trust",
82
+ requirement: `≥ ${demand.trust_score}`,
83
+ provided: `${service.trust_score}`,
84
+ status: "missing",
85
+ impact: "major",
86
+ suggestion: "find a more trustworthy merchant or require more safeguards",
87
+ });
88
+ }
89
+ const total = satisfied.length + missing.length;
90
+ const coverage = total === 0 ? 100 : Math.round((satisfied.length / total) * 100);
91
+ return {
92
+ entity_id: service.id,
93
+ satisfied,
94
+ missing,
95
+ coverage_score: coverage,
96
+ summary: missing.length === 0
97
+ ? `Service fully covers the demand's requirements (${coverage}/100)`
98
+ : `${missing.length} requirement(s) unmet (coverage ${coverage}/100): ${missing.map((m) => m.dimension).join(", ")}`,
99
+ };
100
+ }
@@ -0,0 +1,11 @@
1
+ export * from "./types.js";
2
+ export * from "./user-injection.js";
3
+ export * from "./region.js";
4
+ export * from "./capability.js";
5
+ export * from "./extract.js";
6
+ export * from "./gap.js";
7
+ export * from "./composer.js";
8
+ export * from "./node-game.js";
9
+ export * from "./arbitration-game.js";
10
+ export * from "./builtins/index.js";
11
+ export { EvaluationEngine, getEvaluationEngine, levelFromScore } from "./engine.js";
@@ -0,0 +1,11 @@
1
+ export * from "./types.js";
2
+ export * from "./user-injection.js";
3
+ export * from "./region.js";
4
+ export * from "./capability.js";
5
+ export * from "./extract.js";
6
+ export * from "./gap.js";
7
+ export * from "./composer.js";
8
+ export * from "./node-game.js";
9
+ export * from "./arbitration-game.js";
10
+ export * from "./builtins/index.js";
11
+ export { EvaluationEngine, getEvaluationEngine, levelFromScore } from "./engine.js";
@@ -0,0 +1,34 @@
1
+ import type { ExecutionPath, ParticipationPerspective } from "../participation/radar-core.js";
2
+ export interface NodeForwardInput {
3
+ name: string;
4
+ to_node: string;
5
+ execution_path: ExecutionPath;
6
+ guard?: string;
7
+ consequence?: string;
8
+ }
9
+ export interface NodeGameInput {
10
+ current_node: string;
11
+ perspective: ParticipationPerspective;
12
+ operable: NodeForwardInput[];
13
+ waiting_on: Array<{
14
+ role: string;
15
+ forwards: string[];
16
+ }>;
17
+ }
18
+ export interface NodeGameAction {
19
+ forward: string;
20
+ to_node: string;
21
+ execution_path: ExecutionPath;
22
+ guard?: string;
23
+ favorability: number;
24
+ is_optimal: boolean;
25
+ payoff_note: string;
26
+ risk: "low" | "medium" | "high";
27
+ }
28
+ export interface NodeGameAdvice {
29
+ current_node: string;
30
+ perspective: ParticipationPerspective;
31
+ actions: NodeGameAction[];
32
+ summary: string;
33
+ }
34
+ export declare function evaluateNodeGame(input: NodeGameInput): NodeGameAdvice;
@@ -0,0 +1,57 @@
1
+ export function evaluateNodeGame(input) {
2
+ const actions = input.operable.map((f) => {
3
+ const s = scoreForward(f, input.perspective);
4
+ return {
5
+ forward: f.name,
6
+ to_node: f.to_node,
7
+ execution_path: f.execution_path,
8
+ guard: f.guard,
9
+ favorability: s.favorability,
10
+ is_optimal: false,
11
+ payoff_note: s.payoff,
12
+ risk: s.risk,
13
+ };
14
+ });
15
+ actions.sort((a, b) => b.favorability - a.favorability);
16
+ if (actions.length > 0) {
17
+ actions[0].is_optimal = true;
18
+ }
19
+ return {
20
+ current_node: input.current_node,
21
+ perspective: input.perspective,
22
+ actions,
23
+ summary: buildSummary(input, actions),
24
+ };
25
+ }
26
+ function scoreForward(f, perspective) {
27
+ const isCompletion = !!f.consequence?.startsWith("Completion");
28
+ const isRefund = !!f.consequence?.startsWith("Refund");
29
+ if (perspective === "customer") {
30
+ if (isRefund) {
31
+ return { favorability: 90, payoff: "funds return to you (refund/cancel path)", risk: "low" };
32
+ }
33
+ if (isCompletion) {
34
+ return { favorability: 40, payoff: "releases escrowed funds to the merchant — only confirm if the deliverable matches the agreement", risk: "high" };
35
+ }
36
+ return { favorability: 60, payoff: "advances the order to the next node", risk: "medium" };
37
+ }
38
+ if (perspective === "operator") {
39
+ if (isCompletion) {
40
+ return { favorability: 90, payoff: "settlement + shorter fund-settlement cycle", risk: "low" };
41
+ }
42
+ if (isRefund) {
43
+ return { favorability: 20, payoff: "refund — downside, recorded on-chain (arb-loss/stall stats)", risk: "high" };
44
+ }
45
+ return { favorability: 70, payoff: "advance the workflow to shorten settlement", risk: "low" };
46
+ }
47
+ return { favorability: 50, payoff: "neutral (observer)", risk: "medium" };
48
+ }
49
+ function buildSummary(input, actions) {
50
+ if (actions.length === 0) {
51
+ return input.waiting_on.length > 0
52
+ ? `Waiting on ${input.waiting_on.map((w) => w.role).join(", ")}`
53
+ : `No operable actions at node '${input.current_node || "(entry)"}'`;
54
+ }
55
+ const top = actions[0];
56
+ return `Optimal for ${input.perspective}: '${top.forward}' → '${top.to_node}' (${top.payoff_note})`;
57
+ }
@@ -0,0 +1,10 @@
1
+ export interface Region {
2
+ mode: "remote" | "physical";
3
+ country?: string;
4
+ province?: string;
5
+ city?: string;
6
+ raw: string;
7
+ }
8
+ export type RegionRelation = "exact" | "contains" | "overlap" | "compatible" | "mismatch";
9
+ export declare function parseRegion(raw: string): Region;
10
+ export declare function relateRegion(a: Region, b: Region): RegionRelation;
@@ -0,0 +1,36 @@
1
+ const REMOTE_KEYWORDS = ["remote", "online", "anywhere"];
2
+ export function parseRegion(raw) {
3
+ const trimmed = raw?.trim() ?? "";
4
+ const lower = trimmed.toLowerCase();
5
+ const isRemote = REMOTE_KEYWORDS.some((k) => lower.includes(k));
6
+ if (isRemote) {
7
+ return { mode: "remote", raw: trimmed };
8
+ }
9
+ return { mode: "physical", raw: trimmed };
10
+ }
11
+ export function relateRegion(a, b) {
12
+ if (a.mode === "remote" || b.mode === "remote") {
13
+ return "compatible";
14
+ }
15
+ const na = normalizePhysical(a.raw);
16
+ const nb = normalizePhysical(b.raw);
17
+ if (!na || !nb) {
18
+ return "mismatch";
19
+ }
20
+ if (na === nb) {
21
+ return "exact";
22
+ }
23
+ if (na.includes(nb) || nb.includes(na)) {
24
+ return "contains";
25
+ }
26
+ if (a.province && b.province && a.province === b.province) {
27
+ return "overlap";
28
+ }
29
+ return "mismatch";
30
+ }
31
+ function normalizePhysical(raw) {
32
+ return raw
33
+ .trim()
34
+ .toLowerCase()
35
+ .replace(/\s+/g, "");
36
+ }
@@ -0,0 +1,76 @@
1
+ export interface DataSource {
2
+ id: string;
3
+ description: string;
4
+ evaluation_ids?: string[];
5
+ isEnabled?: (ctx: EvaluationContext) => boolean;
6
+ extract(ctx: EvaluationContext): Promise<Record<string, unknown>> | Record<string, unknown>;
7
+ }
8
+ export interface EvaluationRule {
9
+ id: string;
10
+ description: string;
11
+ dimension: string;
12
+ weight: number;
13
+ evaluation_ids?: string[];
14
+ isEnabled?: (ctx: EvaluationContext) => boolean;
15
+ evaluate(ctx: EvaluationContext): RuleContribution | null;
16
+ }
17
+ export interface RuleContribution {
18
+ score: number;
19
+ weight: number;
20
+ reason?: string;
21
+ matched?: string[];
22
+ mismatched?: string[];
23
+ red_flag?: boolean;
24
+ }
25
+ export interface UserRequirement {
26
+ rule_id: string;
27
+ condition: "require" | "forbid";
28
+ note?: string;
29
+ }
30
+ export interface UserInjection {
31
+ intent?: string;
32
+ preferences?: Record<string, unknown>;
33
+ requirements?: UserRequirement[];
34
+ overrides?: {
35
+ rules?: Record<string, {
36
+ enabled?: boolean;
37
+ weight?: number;
38
+ }>;
39
+ data_sources?: Record<string, {
40
+ enabled?: boolean;
41
+ }>;
42
+ };
43
+ }
44
+ export interface EvaluationContext {
45
+ evaluation_id: string;
46
+ entities: Record<string, unknown>;
47
+ facts: Record<string, unknown>;
48
+ injection?: UserInjection;
49
+ now?: number;
50
+ }
51
+ export type EvaluationLevel = "low" | "medium_low" | "medium_high" | "high";
52
+ export interface EvaluationBreakdown {
53
+ rule_id: string;
54
+ dimension: string;
55
+ score: number;
56
+ weight: number;
57
+ reason?: string;
58
+ matched?: string[];
59
+ mismatched?: string[];
60
+ red_flag?: boolean;
61
+ }
62
+ export interface EvaluationTraceEntry {
63
+ kind: "data_source" | "rule" | "override";
64
+ id: string;
65
+ detail: string;
66
+ }
67
+ export interface EvaluationResult {
68
+ evaluation_id: string;
69
+ total: number;
70
+ level: EvaluationLevel;
71
+ breakdown: EvaluationBreakdown[];
72
+ red_flags: string[];
73
+ blocked: boolean;
74
+ trace: EvaluationTraceEntry[];
75
+ summary: string;
76
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,6 @@
1
+ import type { EvaluationRule, UserInjection } from "./types.js";
2
+ export declare const REQUIREMENT_PASS_THRESHOLD = 60;
3
+ export declare function normalizeInjection(injection?: UserInjection): UserInjection;
4
+ export declare function isRuleEnabled(ruleId: string, injection?: UserInjection): boolean;
5
+ export declare function isDataSourceEnabled(dataSourceId: string, injection?: UserInjection): boolean;
6
+ export declare function effectiveWeight(rule: EvaluationRule, injection?: UserInjection): number;