@wowok/agent-mcp 2.7.1 → 2.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/config/index.js +1 -1
- package/dist/config/runtime.js +1 -238
- package/dist/customer/customer-advice.js +1 -130
- package/dist/customer/index.js +1 -11
- package/dist/customer/industry-risks.js +1 -438
- package/dist/customer/info-puzzle.js +1 -681
- package/dist/customer/order-monitor.js +1 -328
- package/dist/customer/order-strategy.js +1 -373
- package/dist/customer/post-purchase.js +1 -351
- package/dist/customer/preorder-compare.js +1 -34
- package/dist/customer/reminder-system.js +1 -316
- package/dist/customer/risk-assessment.js +1 -397
- package/dist/customer/types.js +1 -13
- package/dist/customer/user-preferences.js +1 -460
- package/dist/evaluation/arbitration-game.d.ts +9 -2
- package/dist/evaluation/arbitration-game.js +1 -48
- package/dist/evaluation/builtins/demand-match.js +1 -153
- package/dist/evaluation/builtins/index.js +1 -10
- package/dist/evaluation/builtins/service-risk.js +1 -55
- package/dist/evaluation/capability.js +1 -13
- package/dist/evaluation/composer.js +1 -40
- package/dist/evaluation/engine.js +1 -175
- package/dist/evaluation/extract.js +1 -115
- package/dist/evaluation/game-strategy.d.ts +27 -0
- package/dist/evaluation/game-strategy.js +1 -0
- package/dist/evaluation/gap.js +1 -100
- package/dist/evaluation/index.d.ts +1 -0
- package/dist/evaluation/index.js +1 -11
- package/dist/evaluation/node-game.d.ts +31 -3
- package/dist/evaluation/node-game.js +1 -57
- package/dist/evaluation/region.js +1 -36
- package/dist/evaluation/types.d.ts +1 -0
- package/dist/evaluation/types.js +1 -1
- package/dist/evaluation/user-injection.js +1 -27
- package/dist/experience/experience-reuse.js +1 -103
- package/dist/experience/index.js +1 -5
- package/dist/experience/intent-distill.js +1 -83
- package/dist/experience/realtime-feedback.js +1 -94
- package/dist/experience/types.js +1 -1
- package/dist/experience/user-profile.js +1 -171
- package/dist/extensions/business-modules.js +1 -287
- package/dist/extensions/capability-manifest.js +1 -781
- package/dist/extensions/constraint-registry.js +1 -198
- package/dist/extensions/index.js +1 -6
- package/dist/extensions/metric-registry.js +1 -257
- package/dist/extensions/mode-evaluator.js +1 -170
- package/dist/extensions/modes.js +1 -499
- package/dist/extensions/registry.js +1 -717
- package/dist/extensions/types.js +1 -1
- package/dist/harness/auto-escalation.js +1 -68
- package/dist/harness/checkpoint.js +1 -129
- package/dist/harness/index.js +1 -78
- package/dist/harness/plan.js +1 -315
- package/dist/harness/recover.js +1 -139
- package/dist/harness/types.js +1 -1
- package/dist/harness/verify.js +1 -237
- package/dist/index.js +1 -273
- package/dist/intent/enrich.js +1 -67
- package/dist/intent/index.js +1 -60
- package/dist/intent/matcher.js +1 -81
- package/dist/intent/store.js +1 -55
- package/dist/intent/types.js +1 -10
- package/dist/knowledge/acquisition-flywheel.js +1 -192
- package/dist/knowledge/allocation-confirm.js +1 -534
- package/dist/knowledge/allocation-context.js +1 -249
- package/dist/knowledge/allocation-ledger.js +1 -463
- package/dist/knowledge/allocation-puzzle.js +1 -298
- package/dist/knowledge/allocation-risk.js +1 -568
- package/dist/knowledge/allocation-templates.js +1 -970
- package/dist/knowledge/allocation-translation.js +1 -585
- package/dist/knowledge/arb-risk.js +1 -210
- package/dist/knowledge/arbitration-confirm.js +1 -559
- package/dist/knowledge/arbitration-context.js +1 -505
- package/dist/knowledge/arbitration-ledger.js +1 -521
- package/dist/knowledge/arbitration-puzzle.js +1 -304
- package/dist/knowledge/arbitration-risk.js +1 -423
- package/dist/knowledge/arbitration-templates.js +1 -276
- package/dist/knowledge/arbitration-translation.js +1 -487
- package/dist/knowledge/arbitration-trust.js +1 -117
- package/dist/knowledge/audit-rules.js +1 -141
- package/dist/knowledge/bridge-risk.js +1 -263
- package/dist/knowledge/contact-risk.js +1 -200
- package/dist/knowledge/contact-templates.js +1 -60
- package/dist/knowledge/demand-confirm.js +1 -206
- package/dist/knowledge/demand-matching.js +1 -132
- package/dist/knowledge/demand-risk.js +1 -240
- package/dist/knowledge/demand-translation.js +1 -354
- package/dist/knowledge/deployment-scanner.js +1 -823
- package/dist/knowledge/dynamic-pricing.js +1 -87
- package/dist/knowledge/examples-scanner-cli.js +1 -26
- package/dist/knowledge/examples-scanner.js +1 -843
- package/dist/knowledge/flywheel-loop.js +1 -404
- package/dist/knowledge/fund-layer.js +1 -973
- package/dist/knowledge/glossary.js +1 -211
- package/dist/knowledge/guard-confirm.js +1 -406
- package/dist/knowledge/guard-context.js +1 -287
- package/dist/knowledge/guard-design-patterns.js +1 -360
- package/dist/knowledge/guard-ledger.js +1 -260
- package/dist/knowledge/guard-lint.js +1 -670
- package/dist/knowledge/guard-migration.js +1 -228
- package/dist/knowledge/guard-puzzle.js +1 -805
- package/dist/knowledge/guard-render.js +1 -700
- package/dist/knowledge/guard-risk.js +1 -1879
- package/dist/knowledge/guard-submission-prompt.js +1 -171
- package/dist/knowledge/guard-templates.js +1 -1105
- package/dist/knowledge/guard-translation.js +1 -1119
- package/dist/knowledge/index.js +1 -436
- package/dist/knowledge/industry-evolution.js +1 -323
- package/dist/knowledge/industry-generalizer.js +1 -381
- package/dist/knowledge/industry-registry.js +1 -174
- package/dist/knowledge/intent-metrics.d.ts +4 -3
- package/dist/knowledge/intent-metrics.js +1 -566
- package/dist/knowledge/machine-confirm.js +1 -559
- package/dist/knowledge/machine-context.js +1 -833
- package/dist/knowledge/machine-ledger.js +1 -338
- package/dist/knowledge/machine-puzzle.js +1 -494
- package/dist/knowledge/machine-render.js +1 -565
- package/dist/knowledge/machine-risk.js +1 -669
- package/dist/knowledge/machine-templates.js +1 -1597
- package/dist/knowledge/machine-topology.js +1 -234
- package/dist/knowledge/machine-translation.js +1 -513
- package/dist/knowledge/mcp-schema-audit-cli.js +1 -45
- package/dist/knowledge/mcp-schema-audit.js +1 -777
- package/dist/knowledge/onchain-constants.js +1 -35
- package/dist/knowledge/order-confirm.js +1 -573
- package/dist/knowledge/order-context.js +1 -390
- package/dist/knowledge/order-ledger.js +1 -341
- package/dist/knowledge/order-puzzle.js +1 -255
- package/dist/knowledge/order-risk.js +1 -653
- package/dist/knowledge/order-templates.js +1 -368
- package/dist/knowledge/order-translation.js +1 -550
- package/dist/knowledge/overrides-loader.js +1 -65
- package/dist/knowledge/passport-confirm.js +1 -531
- package/dist/knowledge/passport-context.js +1 -306
- package/dist/knowledge/passport-ledger.js +1 -282
- package/dist/knowledge/passport-puzzle.js +1 -333
- package/dist/knowledge/passport-risk.js +1 -450
- package/dist/knowledge/passport-templates.js +1 -568
- package/dist/knowledge/passport-translation.js +1 -516
- package/dist/knowledge/payment-risk.js +1 -249
- package/dist/knowledge/permission-confirm.js +1 -426
- package/dist/knowledge/permission-context.js +1 -224
- package/dist/knowledge/permission-ledger.js +1 -403
- package/dist/knowledge/permission-puzzle.js +1 -173
- package/dist/knowledge/permission-risk.js +1 -411
- package/dist/knowledge/permission-templates.js +1 -234
- package/dist/knowledge/permission-translation.js +1 -350
- package/dist/knowledge/personal-risk.js +1 -212
- package/dist/knowledge/process-model.js +1 -160
- package/dist/knowledge/progress-confirm.js +1 -456
- package/dist/knowledge/progress-context.js +1 -452
- package/dist/knowledge/progress-ledger.js +1 -330
- package/dist/knowledge/progress-puzzle.js +1 -219
- package/dist/knowledge/progress-risk.js +1 -461
- package/dist/knowledge/progress-templates.js +1 -228
- package/dist/knowledge/progress-translation.js +1 -405
- package/dist/knowledge/proof-confirm.js +1 -187
- package/dist/knowledge/proof-risk.js +1 -207
- package/dist/knowledge/proof-translation.js +1 -283
- package/dist/knowledge/registrar-risk.js +1 -217
- package/dist/knowledge/repository-confirm.js +1 -286
- package/dist/knowledge/repository-risk.js +1 -373
- package/dist/knowledge/repository-translation.js +1 -445
- package/dist/knowledge/reputation-rules.js +1 -99
- package/dist/knowledge/resource-risk.js +1 -157
- package/dist/knowledge/reward-confirm.js +1 -526
- package/dist/knowledge/reward-context.js +1 -504
- package/dist/knowledge/reward-ledger.js +1 -502
- package/dist/knowledge/reward-puzzle.js +1 -300
- package/dist/knowledge/reward-risk.js +1 -627
- package/dist/knowledge/reward-templates.js +1 -197
- package/dist/knowledge/reward-translation.js +1 -501
- package/dist/knowledge/safety-rules.js +1 -404
- package/dist/knowledge/scenario-modes.js +1 -321
- package/dist/knowledge/service-confirm.js +1 -807
- package/dist/knowledge/service-context.js +1 -403
- package/dist/knowledge/service-ledger.js +1 -609
- package/dist/knowledge/service-puzzle.js +1 -236
- package/dist/knowledge/service-risk.js +1 -651
- package/dist/knowledge/service-templates.js +1 -456
- package/dist/knowledge/service-translation.js +1 -622
- package/dist/knowledge/template-registry.js +1 -353
- package/dist/knowledge/tool-constraints.js +1 -195
- package/dist/knowledge/tools-reference.js +1 -178
- package/dist/knowledge/treasury-confirm.js +1 -512
- package/dist/knowledge/treasury-context.js +1 -363
- package/dist/knowledge/treasury-ledger.js +1 -300
- package/dist/knowledge/treasury-puzzle.js +1 -216
- package/dist/knowledge/treasury-risk.js +1 -440
- package/dist/knowledge/treasury-templates.js +1 -358
- package/dist/knowledge/treasury-translation.js +1 -498
- package/dist/knowledge/trust-metrics.js +1 -198
- package/dist/knowledge/util-risk.js +1 -135
- package/dist/loop-engineering/aggregate.js +1 -132
- package/dist/loop-engineering/context-collect.js +1 -83
- package/dist/loop-engineering/diagnose.js +1 -273
- package/dist/loop-engineering/improve.js +1 -405
- package/dist/loop-engineering/index.js +1 -4
- package/dist/loop-engineering/pipeline.js +1 -56
- package/dist/mode-market/index.js +1 -3
- package/dist/mode-market/registry.js +1 -124
- package/dist/mode-market/review.js +1 -214
- package/dist/mode-market/submission.js +1 -85
- package/dist/participation/collaborator-interest.d.ts +23 -0
- package/dist/participation/collaborator-interest.js +1 -0
- package/dist/participation/customer-interest.d.ts +25 -0
- package/dist/participation/customer-interest.js +1 -0
- package/dist/participation/merchant-interest.js +1 -100
- package/dist/participation/radar-core.d.ts +13 -3
- package/dist/participation/radar-core.js +1 -269
- package/dist/participation/supplier-interest.d.ts +25 -0
- package/dist/participation/supplier-interest.js +1 -0
- package/dist/persona/analyzer.js +1 -66
- package/dist/persona/bridge.js +1 -86
- package/dist/persona/defaults.js +1 -195
- package/dist/persona/experience-bridge.js +1 -23
- package/dist/persona/index.js +1 -71
- package/dist/persona/model.js +1 -111
- package/dist/persona/store.js +1 -62
- package/dist/persona/types.d.ts +3 -1
- package/dist/persona/types.js +1 -5
- package/dist/project/business-puzzle.js +1 -383
- package/dist/project/context-assembly.js +1 -254
- package/dist/project/deployment-bridge.js +1 -120
- package/dist/project/deployment-doc.js +1 -1126
- package/dist/project/edit-planner.js +1 -1342
- package/dist/project/evaluation.js +1 -2011
- package/dist/project/game-theory.js +1 -177
- package/dist/project/graph-builder.js +1 -656
- package/dist/project/graph.js +1 -340
- package/dist/project/handlers.js +1 -1784
- package/dist/project/index.d.ts +1 -0
- package/dist/project/index.js +1 -301
- package/dist/project/intent-analyzer.js +1 -149
- package/dist/project/machine-nodes.js +1 -36
- package/dist/project/merchant-guide.js +1 -264
- package/dist/project/migration.js +1 -125
- package/dist/project/mode-actions.js +1 -309
- package/dist/project/namespace.js +1 -206
- package/dist/project/participation-radar.js +1 -428
- package/dist/project/pipeline-actions.js +1 -109
- package/dist/project/project-store.js +1 -422
- package/dist/project/query.js +1 -153
- package/dist/project/reverse-mapping.d.ts +34 -0
- package/dist/project/reverse-mapping.js +1 -0
- package/dist/project/risk-aggregator.js +1 -295
- package/dist/project/rollback-policy.js +1 -290
- package/dist/project/semantic-assembler.js +1 -345
- package/dist/project/semantic-graph.js +1 -292
- package/dist/project/stage-gate.js +1 -369
- package/dist/project/substep-trace.js +1 -332
- package/dist/project/task-tracker.js +1 -78
- package/dist/role/derivation.d.ts +18 -0
- package/dist/role/derivation.js +1 -0
- package/dist/role/index.d.ts +5 -0
- package/dist/role/index.js +1 -0
- package/dist/role/model.d.ts +8 -0
- package/dist/role/model.js +1 -0
- package/dist/role/resolution.d.ts +11 -0
- package/dist/role/resolution.js +1 -0
- package/dist/role/types.d.ts +11 -0
- package/dist/role/types.js +1 -0
- package/dist/rules.js +1 -52
- package/dist/safety/confirm-gate.js +1 -88
- package/dist/safety/index.js +1 -3
- package/dist/safety/preview.js +1 -52
- package/dist/schema/call/allocation.js +1 -34
- package/dist/schema/call/arbitration.js +1 -113
- package/dist/schema/call/base.d.ts +15 -15
- package/dist/schema/call/base.js +1 -370
- package/dist/schema/call/bridge-handler.js +1 -265
- package/dist/schema/call/bridge.d.ts +7 -7
- package/dist/schema/call/bridge.js +1 -458
- package/dist/schema/call/contact.js +1 -37
- package/dist/schema/call/demand.js +1 -47
- package/dist/schema/call/guard.js +1 -161
- package/dist/schema/call/handler.js +1 -322
- package/dist/schema/call/index.js +1 -20
- package/dist/schema/call/machine.js +1 -193
- package/dist/schema/call/order.js +1 -35
- package/dist/schema/call/payment.js +1 -37
- package/dist/schema/call/permission-handler.js +1 -54
- package/dist/schema/call/permission.js +1 -105
- package/dist/schema/call/personal.js +1 -78
- package/dist/schema/call/progress.js +1 -47
- package/dist/schema/call/proof.js +1 -33
- package/dist/schema/call/repository.js +1 -77
- package/dist/schema/call/reward.js +1 -30
- package/dist/schema/call/semantic.js +1 -1679
- package/dist/schema/call/service.js +1 -184
- package/dist/schema/call/treasury.js +1 -71
- package/dist/schema/common/index.js +1 -407
- package/dist/schema/config/index.js +1 -68
- package/dist/schema/evaluation/index.d.ts +213 -16
- package/dist/schema/evaluation/index.js +1 -356
- package/dist/schema/index.js +1 -17
- package/dist/schema/intent-radar/index.d.ts +13 -13
- package/dist/schema/intent-radar/index.js +1 -89
- package/dist/schema/local/index.d.ts +21 -21
- package/dist/schema/local/index.js +1 -927
- package/dist/schema/local/wip.js +1 -187
- package/dist/schema/messenger/index.d.ts +7 -7
- package/dist/schema/messenger/index.js +1 -475
- package/dist/schema/operations.d.ts +7 -7
- package/dist/schema/operations.js +1 -520
- package/dist/schema/persona/index.d.ts +54 -54
- package/dist/schema/persona/index.js +1 -148
- package/dist/schema/project/index.d.ts +94 -48
- package/dist/schema/project/index.js +1 -2057
- package/dist/schema/query/index.d.ts +423 -7
- package/dist/schema/query/index.js +1 -1646
- package/dist/schema/schema-query/index.js +1 -104
- package/dist/schema/schema-version.js +1 -76
- package/dist/schema/sync-layer4.js +1 -286
- package/dist/schema/task-status.js +1 -36
- package/dist/schema/trust/index.js +1 -314
- package/dist/schema/utils/guard-parser.js +1 -419
- package/dist/schema/utils/guard-query-utils.js +1 -46
- package/dist/schema/utils/node-parser.js +1 -369
- package/dist/schema/utils/object-type-utils.js +1 -35
- package/dist/schema/utils/permission-index-utils.js +1 -7
- package/dist/schema/utils/permission-machine-check.js +1 -121
- package/dist/schema/utils/skills-recommendation.js +1 -77
- package/dist/schema-query/index.js +1 -810
- package/dist/schemas/account_operation.output.json +5 -2
- package/dist/schemas/bridge_operation.output.json +5 -2
- package/dist/schemas/evaluation_operation.output.json +112 -7
- package/dist/schemas/evaluation_operation.schema.json +93 -6
- package/dist/schemas/index.json +1 -1
- package/dist/schemas/intent_radar.output.json +4 -1
- package/dist/schemas/intent_radar.schema.json +4 -1
- package/dist/schemas/local_info_operation.output.json +5 -2
- package/dist/schemas/local_mark_operation.output.json +5 -2
- package/dist/schemas/messenger_operation.output.json +5 -2
- package/dist/schemas/onchain_events.output.json +5 -2
- package/dist/schemas/onchain_operations.output.json +5 -2
- package/dist/schemas/onchain_operations.schema.json +4 -4
- package/dist/schemas/onchain_operations_allocation.schema.json +1 -1
- package/dist/schemas/onchain_operations_machine.schema.json +2 -2
- package/dist/schemas/onchain_operations_service.schema.json +1 -1
- package/dist/schemas/onchain_table_data.output.json +6 -3
- package/dist/schemas/persona_operation.output.json +4 -1
- package/dist/schemas/persona_operation.schema.json +4 -1
- package/dist/schemas/project_operation.output.json +28 -8
- package/dist/schemas/query_toolkit.output.json +8 -5
- package/dist/schemas/wowok_buildin_info.output.json +132 -0
- package/dist/schemas/wowok_buildin_info.schema.json +14 -0
- package/dist/telemetry/index.js +1 -112
- package/dist/telemetry/redact.js +1 -23
- package/dist/telemetry/storage.js +1 -80
- package/dist/tools/handlers/bridge.js +1 -1
- package/dist/tools/handlers/config.js +1 -74
- package/dist/tools/handlers/evaluation.js +1 -123
- package/dist/tools/handlers/file-export.js +1 -90
- package/dist/tools/handlers/intent-radar.js +1 -76
- package/dist/tools/handlers/local.js +1 -53
- package/dist/tools/handlers/messenger.js +1 -188
- package/dist/tools/handlers/onchain.js +1 -1180
- package/dist/tools/handlers/persona.js +1 -89
- package/dist/tools/handlers/project.js +1 -211
- package/dist/tools/handlers/query.js +1 -434
- package/dist/tools/handlers/schema-query.js +1 -176
- package/dist/tools/handlers/task-status.js +1 -26
- package/dist/tools/handlers/trust.js +1 -380
- package/dist/tools/handlers/wip.js +1 -90
- package/dist/tools/index.js +1 -1382
- package/dist/tools/retry.js +1 -85
- package/dist/tools/rules-hook.js +1 -23
- package/dist/tools/shared.js +1 -130
- package/dist/tools/types.js +1 -1
- package/dist/tools/upgrade-check.d.ts +19 -0
- package/dist/tools/upgrade-check.js +1 -0
- package/dist/tools/wip-deploy-assist.js +1 -306
- package/dist/tools/wrap.js +1 -500
- package/package.json +4 -2
|
@@ -1,153 +1 @@
|
|
|
1
|
-
import
|
|
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
|
-
}
|
|
1
|
+
import{requiredCapabilities}from'../capability.js';import{getEvaluationEngine}from'../engine.js';import{extractDemandCapability,extractServiceCapability}from'../extract.js';import{relateRegion}from'../region.js';export const DEMAND_MATCH_EVALUATION='demand_match';const REGION_SCORE={'exact':0x64,'contains':0x55,'compatible':0x3c,'overlap':0x28,'mismatch':0x0},dsCaps={'id':'ds_caps','description':'Extract\x20demand\x20+\x20service\x20capability\x20vectors\x20(either\x20may\x20be\x20pre-computed\x20or\x20raw)','evaluation_ids':[DEMAND_MATCH_EVALUATION],'extract':a=>({'demand_cap':a['entities']['demand_cap']??extractDemandCapability(a['entities']['demand']),'service_cap':a['entities']['service_cap']??extractServiceCapability(a['entities']['service'])})},regionRule={'id':'region','description':'Geographic\x20region\x20relation\x20between\x20demand\x20and\x20service','dimension':'region','weight':0xf,'evaluation_ids':[DEMAND_MATCH_EVALUATION],'evaluate':a=>{const b=a['facts']['demand_cap'],c=a['facts']['service_cap'],e=relateRegion(b['region'],c['region']);return{'score':REGION_SCORE[e],'weight':0xf,'reason':'region\x20'+e};}},industryRule={'id':'industry','description':'Industry\x20scenario\x20match','dimension':'industry','weight':0x14,'evaluation_ids':[DEMAND_MATCH_EVALUATION],'evaluate':a=>{const b=a['facts']['demand_cap'],c=a['facts']['service_cap'];if(b['industry']==='general'||c['industry']==='general')return{'score':0x32,'weight':0x14,'reason':'industry\x20unknown\x20(neutral)'};const e=b['industry']===c['industry']?0x64:0x0;return{'score':e,'weight':0x14,'reason':b['industry']+'\x20vs\x20'+c['industry']};}},priceRule={'id':'price','description':'Service\x20price\x20within\x20demand\x20budget','dimension':'price','weight':0xf,'evaluation_ids':[DEMAND_MATCH_EVALUATION],'evaluate':a=>{const b=a['facts']['demand_cap'],c=a['facts']['service_cap'];if(b['price_max']===undefined||c['price_min']===undefined)return{'score':0x32,'weight':0xf,'reason':'price\x20unknown\x20(neutral)'};if(c['price_min']<=b['price_max'])return{'score':0x64,'weight':0xf,'reason':'within\x20budget'};if(c['price_min']<=b['price_max']*0x6en/0x64n)return{'score':0x32,'weight':0xf,'reason':'slightly\x20over\x20budget'};return{'score':0x0,'weight':0xf,'reason':'over\x20budget'};}},trustRule={'id':'trust','description':'Service\x20trust\x20score','dimension':'trust','weight':0xf,'evaluation_ids':[DEMAND_MATCH_EVALUATION],'evaluate':a=>{const b=a['facts']['service_cap'],c=b['trust_score'],d=c>=0x4b?0x64:c>=0x32?0x3c:c>=0x19?0x1e:0x0;return{'score':d,'weight':0xf,'reason':'trust\x20'+c};}},capabilitiesRule={'id':'capabilities','description':'Demand\x20capability\x20requirements\x20covered\x20by\x20the\x20service','dimension':'capabilities','weight':0x1e,'evaluation_ids':[DEMAND_MATCH_EVALUATION],'evaluate':a=>{const b=a['facts']['demand_cap'],c=a['facts']['service_cap'],e=requiredCapabilities(b['capabilities']);if(e['length']===0x0)return{'score':0x32,'weight':0x1e,'reason':'no\x20capability\x20requirement\x20(neutral)'};const f=e['filter'](g=>c['capabilities'][g]);return{'score':Math['round'](f['length']/e['length']*0x64),'weight':0x1e,'matched':f,'mismatched':e['filter'](g=>!c['capabilities'][g]),'reason':f['length']+'/'+e['length']+'\x20required\x20capabilities\x20covered'};}},tagsRule={'id':'tags','description':'Keyword/tag\x20overlap','dimension':'tags','weight':0x5,'evaluation_ids':[DEMAND_MATCH_EVALUATION],'evaluate':a=>{const b=a['facts']['demand_cap'],c=a['facts']['service_cap'],e=new Set((b['keywords']??[])['map'](h=>h['toLowerCase']())),f=new Set([...c['tags']??[],...c['keywords']??[]]['map'](h=>h['toLowerCase']()));if(e['size']===0x0)return{'score':0x32,'weight':0x5,'reason':'no\x20keywords\x20(neutral)'};const g=[...e]['filter'](h=>f['has'](h))['length'];return{'score':Math['round'](g/e['size']*0x64),'weight':0x5,'reason':g+'/'+e['size']+'\x20keywords'};}};export function registerDemandMatchEvaluation(a=getEvaluationEngine()){a['registerDataSource'](dsCaps);for(const b of[regionRule,industryRule,priceRule,trustRule,capabilitiesRule,tagsRule]){a['registerRule'](b);}}export async function matchDemandToServices(a,b,c,d=0x5){const e=getEvaluationEngine(),f=[];for(const g of b){const h=await e['evaluate'](DEMAND_MATCH_EVALUATION,{'demand_cap':a,'service':g},c);f['push']({'service':g,'result':h});}return f['sort']((i,j)=>j['result']['total']-i['result']['total']),f['slice'](0x0,d);}export async function matchServiceToDemands(a,b,c,d=0x5){const e=getEvaluationEngine(),f=[];for(const g of b){const h=await e['evaluate'](DEMAND_MATCH_EVALUATION,{'service_cap':a,'demand':g},c);f['push']({'demand':g,'result':h});}return f['sort']((i,j)=>j['result']['total']-i['result']['total']),f['slice'](0x0,d);}
|
|
@@ -1,10 +1 @@
|
|
|
1
|
-
import
|
|
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";
|
|
1
|
+
import{getEvaluationEngine}from'../engine.js';import{registerDemandMatchEvaluation}from'./demand-match.js';import{registerServiceRiskEvaluation}from'./service-risk.js';export function registerBuiltinEvaluations(){const a=getEvaluationEngine();registerDemandMatchEvaluation(a),registerServiceRiskEvaluation(a);}export{registerDemandMatchEvaluation,matchDemandToServices,matchServiceToDemands,DEMAND_MATCH_EVALUATION}from'./demand-match.js';export{registerServiceRiskEvaluation,assessServiceRisk,SERVICE_RISK_EVALUATION}from'./service-risk.js';
|
|
@@ -1,55 +1 @@
|
|
|
1
|
-
import
|
|
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
|
-
}
|
|
1
|
+
import{assembleInfoPuzzle}from'../../customer/info-puzzle.js';import{assessWorkflowRisk,assessFundRisk,assessTrustRisk,assessBehaviorRisk}from'../../customer/risk-assessment.js';import{getEvaluationEngine}from'../engine.js';export const SERVICE_RISK_EVALUATION='service_risk';const dsPuzzle={'id':'ds_puzzle','description':'Assemble\x20the\x20service\x20info\x20puzzle\x20from\x20raw\x20chain\x20data','evaluation_ids':[SERVICE_RISK_EVALUATION],'extract':a=>{const b=a['entities']['service_id'],c=a['entities']['puzzle_raw'],d=a['entities']['depth']??'preorder';return{'puzzle':assembleInfoPuzzle(b,c,d)};}};function dimensionRule(a,b,c,d){return{'id':a,'description':b+'\x20risk\x20dimension','dimension':b,'weight':c,'evaluation_ids':[SERVICE_RISK_EVALUATION],'evaluate':e=>{const f=e['facts']['puzzle'],g=d(f),h=g['max_score']>0x0?Math['round'](g['score']/g['max_score']*0x64):0x0,i=g['checks']['filter'](l=>l['passed']),j=g['checks']['filter'](l=>!l['passed']),k=j['filter'](l=>l['advice']?.['startsWith']('🔴'));return{'score':h,'weight':c,'reason':k['length']>0x0?k['map'](l=>'['+g['name']+']\x20'+l['description']+':\x20'+l['advice'])['join'](';\x20'):g['name']+'\x20'+g['score']+'/'+g['max_score'],'matched':i['map'](l=>l['id']),'mismatched':j['map'](l=>l['id']),'red_flag':k['length']>0x0};}};}const workflowRule=dimensionRule('workflow','workflow',0x23,assessWorkflowRisk),fundRule=dimensionRule('fund','fund',0x19,assessFundRisk),trustRule=dimensionRule('trust','trust',0x14,assessTrustRisk),behaviorRule=dimensionRule('behavior','behavior',0x14,assessBehaviorRisk);export function registerServiceRiskEvaluation(a=getEvaluationEngine()){a['registerDataSource'](dsPuzzle);for(const b of[workflowRule,fundRule,trustRule,behaviorRule]){a['registerRule'](b);}}export async function assessServiceRisk(a,b,c,d='preorder'){return getEvaluationEngine()['evaluate'](SERVICE_RISK_EVALUATION,{'service_id':a,'puzzle_raw':b,'depth':d},c);}
|
|
@@ -1,13 +1 @@
|
|
|
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
|
-
}
|
|
1
|
+
export const REQUIREMENT_CAPABILITY_KEYS=['has_arbitration','has_refund_path','has_milestone_nodes','has_compensation_fund','has_wip_verification','has_messenger','has_buy_guard','has_dynamic_pricing'];export function requiredCapabilities(a){return REQUIREMENT_CAPABILITY_KEYS['filter'](b=>a[b]===!![]);}
|
|
@@ -1,40 +1 @@
|
|
|
1
|
-
import
|
|
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
|
-
}
|
|
1
|
+
import{requiredCapabilities}from'./capability.js';import{relateRegion}from'./region.js';export function composeServicesForDemand(a,b){const c=requiredCapabilities(a['capabilities']),d=new Set(c),e=[],f=b['filter'](i=>relateRegion(a['region'],i['region'])!=='mismatch');while(d['size']>0x0){let i=null;for(const j of f){if(e['some'](m=>m['id']===j['id']))continue;const l=c['filter'](m=>d['has'](m)&&j['capabilities'][m]);(!i||l['length']>i['covered']['length'])&&(i={'id':j['id'],'covered':l});}if(!i||i['covered']['length']===0x0)break;e['push'](i);for(const m of i['covered'])d['delete'](m);}const g=c['length']===0x0?0x64:Math['round']((c['length']-d['size'])/c['length']*0x64),h=d['size']===0x0?'ready':e['length']>0x0?'needs_supply_chain':'infeasible';return{'demand':a['id'],'services':e,'coverage_score':g,'remaining_missing':[...d],'feasibility':h,'summary':d['size']===0x0?'Composite\x20of\x20'+e['length']+'\x20service(s)\x20covers\x20all\x20'+c['length']+'\x20requirements':'Composite\x20of\x20'+e['length']+'\x20service(s)\x20covers\x20'+g+'/100;\x20missing:\x20'+([...d]['join'](',\x20')||'none')};}
|
|
@@ -1,175 +1 @@
|
|
|
1
|
-
import
|
|
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
|
-
}
|
|
1
|
+
import{REQUIREMENT_PASS_THRESHOLD,effectiveWeight,isDataSourceEnabled,isRuleEnabled,normalizeInjection}from'./user-injection.js';const LEVELS=[{'min':0x55,'level':'low'},{'min':0x46,'level':'medium_low'},{'min':0x32,'level':'medium_high'},{'min':0x0,'level':'high'}];export function levelFromScore(a){for(const b of LEVELS){if(a>=b['min'])return b['level'];}return'high';}function appliesTo(a,b){if(!a||a['length']===0x0)return!![];return a['includes'](b);}export class EvaluationEngine{static ['instance']=null;['dataSources']=new Map();['rules']=new Map();static['Instance'](){return!EvaluationEngine['instance']&&(EvaluationEngine['instance']=new EvaluationEngine()),EvaluationEngine['instance'];}['registerDataSource'](a){if(!a['id']||this['dataSources']['has'](a['id']))return![];return this['dataSources']['set'](a['id'],a),!![];}['unregisterDataSource'](a){return this['dataSources']['delete'](a);}['registerRule'](a){if(!a['id']||this['rules']['has'](a['id']))return![];return this['rules']['set'](a['id'],a),!![];}['unregisterRule'](a){return this['rules']['delete'](a);}['getRule'](a){return this['rules']['get'](a);}['listRules'](){return Array['from'](this['rules']['values']());}['getDataSource'](a){return this['dataSources']['get'](a);}['listDataSources'](){return Array['from'](this['dataSources']['values']());}async['evaluate'](a,b,c){const d=normalizeInjection(c),e={'evaluation_id':a,'entities':b,'facts':{},'injection':d,'now':Date['now']()},f=[],g=Array['from'](this['dataSources']['values']())['filter'](m=>appliesTo(m['evaluation_ids'],a))['sort']((m,n)=>(m['priority']??0x0)-(n['priority']??0x0));for(const m of g){if(!isDataSourceEnabled(m['id'],d)){f['push']({'kind':'override','id':m['id'],'detail':'data\x20source\x20disabled\x20by\x20user\x20override'});continue;}if(m['isEnabled']&&!m['isEnabled'](e))continue;const n=await m['extract'](e);Object['assign'](e['facts'],n),f['push']({'kind':'data_source','id':m['id'],'detail':'extracted\x20'+Object['keys'](n)['length']+'\x20fact(s)'});}const h=[],i=[];for(const o of this['rules']['values']()){if(!appliesTo(o['evaluation_ids'],a))continue;if(!isRuleEnabled(o['id'],d)){f['push']({'kind':'override','id':o['id'],'detail':'rule\x20disabled\x20by\x20user\x20override'});continue;}if(o['isEnabled']&&!o['isEnabled'](e))continue;const p=o['evaluate'](e);if(!p)continue;const q=effectiveWeight(o,d);h['push']({'rule_id':o['id'],'dimension':o['dimension'],'score':p['score'],'weight':q,'reason':p['reason'],'matched':p['matched'],'mismatched':p['mismatched'],'red_flag':p['red_flag']}),p['red_flag']&&i['push'](p['reason']??o['id']+'\x20triggered\x20a\x20hard\x20block'),f['push']({'kind':'rule','id':o['id'],'detail':'score='+p['score']+'\x20weight='+q});}const j=aggregateScore(h);let k=i['length']>0x0;for(const r of d['requirements']??[]){const s=h['find'](t=>t['rule_id']===r['rule_id']);if(r['condition']==='require')(!s||s['score']<REQUIREMENT_PASS_THRESHOLD||s['red_flag'])&&(k=!![],i['push'](r['note']??'Requirement\x20requires\x20rule\x20\x27'+r['rule_id']+'\x27\x20to\x20pass'));else r['condition']==='forbid'&&(s&&s['red_flag']&&(k=!![],i['push'](r['note']??'Requirement\x20forbids\x20rule\x20\x27'+r['rule_id']+'\x27\x20from\x20triggering')));}const l=buildSummary(a,j,h,i,k);return{'evaluation_id':a,'total':j,'level':levelFromScore(j),'breakdown':h,'red_flags':i,'blocked':k,'trace':f,'summary':l};}}function aggregateScore(a){if(a['length']===0x0)return 0x0;let c=0x0,d=0x0;for(const e of a){c+=e['score']*e['weight'],d+=e['weight'];}if(d<=0x0)return 0x0;return clamp(Math['round'](c/d),0x0,0x64);}function clamp(a,b,c){return Math['max'](b,Math['min'](c,a));}function buildSummary(a,b,c,d,e){const f=['Evaluation\x20\x27'+a+'\x27:\x20score\x20'+b+'/100'];return e?f['push']('BLOCKED\x20('+d['length']+'\x20red\x20flag(s))'):f['push'](c['length']+'\x20rule(s)\x20evaluated'),f['join']('\x20—\x20');}export function getEvaluationEngine(){return EvaluationEngine['Instance']();}
|
|
@@ -1,115 +1 @@
|
|
|
1
|
-
import
|
|
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
|
-
}
|
|
1
|
+
import{parseRegion}from'./region.js';import{findSimilarIndustries,inferTraitsFromDescription}from'../knowledge/industry-generalizer.js';const BUILTIN_SCENARIOS=['freelance','rental','education','travel','subscription','retail'];function enrichFromDescription(a){const b=a?.['trim']();if(!b)return{'industry':'general','industry_confidence':0x0,'tags':[],'keywords':[]};const {traits:c,confidence:d,matched_keywords:e}=inferTraitsFromDescription(b),f=findSimilarIndustries(c,0x3),g=f[0x0],h=g&&BUILTIN_SCENARIOS['includes'](g['industry'])?g['industry']:'general',i=e['length']>0x0||(g?.['similarity']??0x0)>0.2;return{'industry':i?h:'general','industry_confidence':i?Math['max'](d,g?.['similarity']??0x0):0x0,'tags':i?f['slice'](0x0,0x3)['map'](j=>j['industry']):[],'keywords':e};}export function extractServiceCapability(a,b){const c=a['sales']??[],d=c['map'](j=>toBigInt(j['price']))['filter'](j=>j!==undefined),e=a['arbitrations']??[],f=toBigInt(a['compensation_fund'])??0x0n,g=enrichFromDescription(a['description']),h={'has_arbitration':e['length']>0x0,'has_refund_path':e['length']>0x0&&f>0x0n,'has_milestone_nodes':![],'has_compensation_fund':f>0x0n,'has_wip_verification':c['some'](j=>!!j['wip_hash']),'has_messenger':a['um']!=null,'has_buy_guard':a['buy_guard']!=null,'has_dynamic_pricing':![],'is_published':a['bPublished']===!![],'is_paused':a['bPaused']===!![]},i={'id':a['object'],'kind':'service','owner':a['owner']??'','industry':g['industry'],'industry_confidence':g['industry_confidence'],'region':parseRegion(a['location']),'price_min':d['length']>0x0?minBigInt(d):undefined,'price_max':d['length']>0x0?maxBigInt(d):undefined,'token_type':'','ticket_size':'medium','trust_score':0x32,'reputation_like_ratio':0x1,'arbitration_independent':![],'merchant_history_count':0x0,'capabilities':h,'tags':g['tags'],'keywords':g['keywords']};return{...i,...b};}export function extractDemandCapability(a,b){const c=enrichFromDescription(a['description']),d={'id':a['object'],'kind':'demand','owner':a['owner']??'','industry':c['industry'],'industry_confidence':c['industry_confidence'],'region':parseRegion(a['location']),'price_min':undefined,'price_max':undefined,'token_type':'','ticket_size':'medium','trust_score':0x32,'reputation_like_ratio':0x1,'arbitration_independent':![],'merchant_history_count':0x0,'capabilities':{'has_arbitration':![],'has_refund_path':![],'has_milestone_nodes':![],'has_compensation_fund':![],'has_wip_verification':![],'has_messenger':a['um']!=null,'has_buy_guard':![],'has_dynamic_pricing':![],'is_published':!![],'is_paused':![]},'tags':c['tags'],'keywords':c['keywords']};return{...d,...b};}function toBigInt(a){if(a===undefined||a===null)return undefined;try{return BigInt(a);}catch{return undefined;}}function minBigInt(a){return a['reduce']((c,d)=>c<d?c:d);}function maxBigInt(a){return a['reduce']((c,d)=>c>d?c:d);}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { CommercialRole } from "../role/types.js";
|
|
2
|
+
export type OperationOutcome = "completion" | "refund" | "advance";
|
|
3
|
+
export type RiskAppetite = "conservative" | "balanced" | "aggressive";
|
|
4
|
+
export declare const OUTCOME_SEMANTICS: Record<OperationOutcome, string[]>;
|
|
5
|
+
export interface RoleInterests {
|
|
6
|
+
prefer: string[];
|
|
7
|
+
avoid: string[];
|
|
8
|
+
sensitivity: number;
|
|
9
|
+
}
|
|
10
|
+
export declare const ROLE_INTERESTS: Record<CommercialRole, RoleInterests>;
|
|
11
|
+
export declare function classifyOutcome(consequence?: string): OperationOutcome;
|
|
12
|
+
export declare function appetiteMultiplier(appetite?: RiskAppetite): number;
|
|
13
|
+
export declare function interestsOf(role: CommercialRole): RoleInterests;
|
|
14
|
+
export interface PersonaDrive {
|
|
15
|
+
risk_appetite?: RiskAppetite;
|
|
16
|
+
requirements?: string[];
|
|
17
|
+
}
|
|
18
|
+
export declare function resolveInterests(role: CommercialRole, drive?: PersonaDrive): RoleInterests;
|
|
19
|
+
export interface OutcomeEvaluation {
|
|
20
|
+
gain_score: number;
|
|
21
|
+
risk_score: number;
|
|
22
|
+
net_score: number;
|
|
23
|
+
gains: string[];
|
|
24
|
+
risks: string[];
|
|
25
|
+
}
|
|
26
|
+
export declare function evaluateOutcome(outcome: OperationOutcome, role: CommercialRole, drive?: PersonaDrive): OutcomeEvaluation;
|
|
27
|
+
export declare function consistencyScore(outcome: OperationOutcome, role: CommercialRole): number;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const OUTCOME_SEMANTICS={'completion':['fund_released_to_merchant','refund_leverage_given_up'],'refund':['fund_returned_to_buyer','arbitration_review_triggered'],'advance':['node_advanced']};export const ROLE_INTERESTS={'customer':{'prefer':['fund_returned_to_buyer'],'avoid':['fund_released_to_merchant','refund_leverage_given_up'],'sensitivity':0x1},'merchant':{'prefer':['fund_released_to_merchant'],'avoid':['fund_returned_to_buyer','arbitration_review_triggered'],'sensitivity':0x1},'collaborator':{'prefer':['node_advanced'],'avoid':[],'sensitivity':0x1},'supplier':{'prefer':['fund_released_to_merchant','node_advanced'],'avoid':['fund_returned_to_buyer'],'sensitivity':0x1},'prospect':{'prefer':['fund_returned_to_buyer'],'avoid':['fund_released_to_merchant','arbitration_review_triggered','refund_leverage_given_up'],'sensitivity':0x1},'arbitrator':{'prefer':[],'avoid':['arbitration_review_triggered'],'sensitivity':0x1},'system':{'prefer':[],'avoid':[],'sensitivity':0x1}};export function classifyOutcome(a){if(a?.['startsWith']('Completion'))return'completion';if(a?.['startsWith']('Refund'))return'refund';return'advance';}export function appetiteMultiplier(a){switch(a){case'conservative':return 1.5;case'aggressive':return 0.6;default:return 0x1;}}export function interestsOf(a){return ROLE_INTERESTS[a]??{'prefer':[],'avoid':[],'sensitivity':0x1};}function dedupe(a){return Array['from'](new Set(a));}export function resolveInterests(a,b){const c=interestsOf(a),d=c['sensitivity']*appetiteMultiplier(b?.['risk_appetite']),e=[...c['prefer']],f=[...c['avoid']];for(const g of b?.['requirements']??[]){const h=g['toLowerCase'](),i=/forbid|never|\bno\b/['test'](h);if(h['includes']('arbitration')&&i)f['push']('arbitration_review_triggered');if(h['includes']('refund')&&!i)e['push']('fund_returned_to_buyer');if((h['includes']('upfront')||h['includes']('before\x20delivery'))&&i)f['push']('fund_released_to_merchant');if(h['includes']('milestone')&&!i)e['push']('node_advanced');}return{'prefer':dedupe(e),'avoid':dedupe(f),'sensitivity':d};}export function evaluateOutcome(a,b,c){const d=OUTCOME_SEMANTICS[a]??[],e=resolveInterests(b,c),f=e['sensitivity'],g=[],h=[];for(const l of d){if(e['prefer']['includes'](l))g['push'](l);if(e['avoid']['includes'](l))h['push'](l);}const i=g['length']*0x14,j=Math['round'](h['length']*0x19*f),k=Math['max'](0x0,Math['min'](0x64,0x3c+i-j));return{'gain_score':i,'risk_score':j,'net_score':k,'gains':g,'risks':h};}export function consistencyScore(a,b){return evaluateOutcome(a,b)['net_score'];}
|