@wowok/agent-mcp 2.6.9 → 2.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -2
- package/dist/customer/risk-assessment.d.ts +5 -1
- package/dist/customer/risk-assessment.js +4 -4
- package/dist/evaluation/arbitration-game.d.ts +16 -0
- package/dist/evaluation/arbitration-game.js +48 -0
- package/dist/evaluation/builtins/demand-match.d.ts +15 -0
- package/dist/evaluation/builtins/demand-match.js +153 -0
- package/dist/evaluation/builtins/index.d.ts +3 -0
- package/dist/evaluation/builtins/index.js +10 -0
- package/dist/evaluation/builtins/service-risk.d.ts +6 -0
- package/dist/evaluation/builtins/service-risk.js +55 -0
- package/dist/evaluation/capability.d.ts +50 -0
- package/dist/evaluation/capability.js +13 -0
- package/dist/evaluation/composer.d.ts +13 -0
- package/dist/evaluation/composer.js +40 -0
- package/dist/evaluation/engine.d.ts +18 -0
- package/dist/evaluation/engine.js +175 -0
- package/dist/evaluation/extract.d.ts +30 -0
- package/dist/evaluation/extract.js +115 -0
- package/dist/evaluation/gap.d.ts +2 -0
- package/dist/evaluation/gap.js +100 -0
- package/dist/evaluation/index.d.ts +11 -0
- package/dist/evaluation/index.js +11 -0
- package/dist/evaluation/node-game.d.ts +34 -0
- package/dist/evaluation/node-game.js +57 -0
- package/dist/evaluation/region.d.ts +10 -0
- package/dist/evaluation/region.js +36 -0
- package/dist/evaluation/types.d.ts +76 -0
- package/dist/evaluation/types.js +1 -0
- package/dist/evaluation/user-injection.d.ts +6 -0
- package/dist/evaluation/user-injection.js +27 -0
- package/dist/examples/education-contact-create.json +40 -0
- package/dist/examples/freelance-contact-create.json +40 -0
- package/dist/examples/insurance-machine-create.json +1 -1
- package/dist/examples/insurance-service-allocators.json +1 -1
- package/dist/examples/machine-publish.json +1 -1
- package/dist/examples/rental-ziroom-service-create.json +1 -1
- package/dist/examples/retail-adv-guard-messenger-proof-create.json +1 -1
- package/dist/examples/retail-myshop-service-create.json +1 -1
- package/dist/examples/retail-myshop-service-customer-required.json +1 -1
- package/dist/examples/subscription-contact-create.json +40 -0
- package/dist/examples/threebody-machine-create.json +1 -1
- package/dist/examples/travel-machine-create.json +1 -1
- package/dist/examples/travel-service-create.json +1 -1
- package/dist/harness/plan.js +42 -3
- package/dist/intent/enrich.d.ts +1 -0
- package/dist/intent/enrich.js +67 -0
- package/dist/intent/index.d.ts +23 -0
- package/dist/intent/index.js +60 -0
- package/dist/intent/matcher.d.ts +2 -0
- package/dist/intent/matcher.js +81 -0
- package/dist/intent/store.d.ts +19 -0
- package/dist/intent/store.js +55 -0
- package/dist/intent/types.d.ts +33 -0
- package/dist/intent/types.js +10 -0
- package/dist/knowledge/arbitration-risk.js +1 -11
- package/dist/knowledge/contact-templates.d.ts +27 -0
- package/dist/knowledge/contact-templates.js +60 -0
- package/dist/knowledge/examples-scanner.js +21 -3
- package/dist/knowledge/fund-layer.js +8 -4
- package/dist/knowledge/industry-generalizer.js +21 -21
- package/dist/knowledge/machine-risk.js +0 -1
- package/dist/knowledge/mcp-schema-audit.d.ts +1 -1
- package/dist/knowledge/mcp-schema-audit.js +8 -4
- package/dist/knowledge/service-risk.js +38 -2
- package/dist/knowledge/service-templates.js +1 -1
- package/dist/knowledge/service-translation.js +2 -2
- package/dist/knowledge/template-registry.d.ts +1 -1
- package/dist/knowledge/template-registry.js +13 -1
- package/dist/knowledge/tools-reference.js +23 -0
- package/dist/persona/analyzer.d.ts +16 -0
- package/dist/persona/analyzer.js +66 -0
- package/dist/persona/bridge.d.ts +5 -0
- package/dist/persona/bridge.js +86 -0
- package/dist/persona/defaults.d.ts +4 -0
- package/dist/persona/defaults.js +195 -0
- package/dist/persona/experience-bridge.d.ts +3 -0
- package/dist/persona/experience-bridge.js +23 -0
- package/dist/persona/index.d.ts +18 -0
- package/dist/persona/index.js +71 -0
- package/dist/persona/model.d.ts +7 -0
- package/dist/persona/model.js +111 -0
- package/dist/persona/store.d.ts +19 -0
- package/dist/persona/store.js +62 -0
- package/dist/persona/types.d.ts +43 -0
- package/dist/persona/types.js +5 -0
- package/dist/project/handlers.d.ts +5 -0
- package/dist/project/handlers.js +23 -1
- package/dist/project/semantic-graph.js +47 -0
- package/dist/rules.d.ts +2 -0
- package/dist/rules.js +43 -0
- package/dist/schema/call/semantic.js +23 -1
- package/dist/schema/call/service.js +7 -1
- package/dist/schema/evaluation/index.d.ts +4239 -0
- package/dist/schema/evaluation/index.js +356 -0
- package/dist/schema/index.d.ts +4 -0
- package/dist/schema/index.js +4 -0
- package/dist/schema/intent-radar/index.d.ts +284 -0
- package/dist/schema/intent-radar/index.js +89 -0
- package/dist/schema/messenger/index.d.ts +171 -0
- package/dist/schema/messenger/index.js +5 -0
- package/dist/schema/operations.js +1 -1
- package/dist/schema/persona/index.d.ts +1985 -0
- package/dist/schema/persona/index.js +148 -0
- package/dist/schema/project/index.d.ts +2 -2
- package/dist/schema/query/index.js +6 -0
- package/dist/schema/sync-layer4.d.ts +1 -1
- package/dist/schema/sync-layer4.js +9 -5
- package/dist/schema/task-status.d.ts +168 -0
- package/dist/schema/task-status.js +36 -0
- package/dist/schema/trust/index.js +1 -1
- package/dist/schemas/evaluation_operation.output.json +677 -0
- package/dist/schemas/evaluation_operation.schema.json +903 -0
- package/dist/schemas/index.json +25 -1
- package/dist/schemas/intent_radar.output.json +229 -0
- package/dist/schemas/intent_radar.schema.json +135 -0
- package/dist/schemas/messenger_operation.output.json +14 -0
- package/dist/schemas/messenger_operation.schema.json +18 -0
- package/dist/schemas/onchain_operations.schema.json +2 -2
- package/dist/schemas/onchain_operations_service.schema.json +2 -2
- package/dist/schemas/persona_operation.output.json +389 -0
- package/dist/schemas/persona_operation.schema.json +247 -0
- package/dist/schemas/query_task_status.output.json +115 -0
- package/dist/schemas/query_task_status.schema.json +24 -0
- package/dist/schemas/query_toolkit.output.json +1 -1
- package/dist/schemas/trust_score.schema.json +1 -1
- package/dist/tools/handlers/evaluation.d.ts +2 -0
- package/dist/tools/handlers/evaluation.js +123 -0
- package/dist/tools/handlers/intent-radar.d.ts +2 -0
- package/dist/tools/handlers/intent-radar.js +76 -0
- package/dist/tools/handlers/onchain.js +98 -0
- package/dist/tools/handlers/persona.d.ts +4 -0
- package/dist/tools/handlers/persona.js +89 -0
- package/dist/tools/handlers/task-status.d.ts +0 -168
- package/dist/tools/handlers/task-status.js +0 -29
- package/dist/tools/index.js +83 -7
- package/dist/tools/wip-deploy-assist.d.ts +1 -1
- package/dist/tools/wip-deploy-assist.js +33 -5
- package/package.json +2 -2
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export const REQUIREMENT_PASS_THRESHOLD = 60;
|
|
2
|
+
export function normalizeInjection(injection) {
|
|
3
|
+
return {
|
|
4
|
+
intent: injection?.intent,
|
|
5
|
+
preferences: injection?.preferences,
|
|
6
|
+
requirements: injection?.requirements ?? [],
|
|
7
|
+
overrides: injection?.overrides ?? {},
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
export function isRuleEnabled(ruleId, injection) {
|
|
11
|
+
const override = injection?.overrides?.rules?.[ruleId];
|
|
12
|
+
if (override && override.enabled !== undefined)
|
|
13
|
+
return override.enabled;
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
16
|
+
export function isDataSourceEnabled(dataSourceId, injection) {
|
|
17
|
+
const override = injection?.overrides?.data_sources?.[dataSourceId];
|
|
18
|
+
if (override && override.enabled !== undefined)
|
|
19
|
+
return override.enabled;
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
export function effectiveWeight(rule, injection) {
|
|
23
|
+
const override = injection?.overrides?.rules?.[rule.id];
|
|
24
|
+
if (override && override.weight !== undefined)
|
|
25
|
+
return override.weight;
|
|
26
|
+
return rule.weight;
|
|
27
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"title": "Create Education Contact Object",
|
|
3
|
+
"description": "Create a named Contact object for an education provider, with a Permission reference and an IM entry pointing at the support account",
|
|
4
|
+
"tags": ["contact", "messenger", "ims", "education"],
|
|
5
|
+
"industry": "education",
|
|
6
|
+
"operation_type": "contact",
|
|
7
|
+
"source": "Template-generated from K2 industry defaults (not chain-verified)",
|
|
8
|
+
"verified": false,
|
|
9
|
+
"network": "testnet",
|
|
10
|
+
"call": {
|
|
11
|
+
"tool": "onchain_operations",
|
|
12
|
+
"operation_type": "contact",
|
|
13
|
+
"data": {
|
|
14
|
+
"object": {
|
|
15
|
+
"name": "education_contact",
|
|
16
|
+
"permission": "education_permission",
|
|
17
|
+
"replaceExistName": true
|
|
18
|
+
},
|
|
19
|
+
"description": "Education provider contact — course info, attendance, and refund policy",
|
|
20
|
+
"ims": {
|
|
21
|
+
"op": "add",
|
|
22
|
+
"im": [
|
|
23
|
+
{
|
|
24
|
+
"at": "education_support",
|
|
25
|
+
"description": "Primary support account"
|
|
26
|
+
}
|
|
27
|
+
]
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"env": {
|
|
31
|
+
"network": "testnet",
|
|
32
|
+
"no_cache": true,
|
|
33
|
+
"confirmed": true
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
"notes": [
|
|
37
|
+
"Bind this Contact to the education Service via the service call's 'um' field.",
|
|
38
|
+
"Tuition should be escrowed and released per lesson (1/N) to prevent run-away disputes."
|
|
39
|
+
]
|
|
40
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"title": "Create Freelance Contact Object",
|
|
3
|
+
"description": "Create a named Contact object for a freelance service provider, with a Permission reference and an IM entry pointing at the provider account",
|
|
4
|
+
"tags": ["contact", "messenger", "ims", "freelance"],
|
|
5
|
+
"industry": "freelance",
|
|
6
|
+
"operation_type": "contact",
|
|
7
|
+
"source": "Template-generated from K2 industry defaults (not chain-verified)",
|
|
8
|
+
"verified": false,
|
|
9
|
+
"network": "testnet",
|
|
10
|
+
"call": {
|
|
11
|
+
"tool": "onchain_operations",
|
|
12
|
+
"operation_type": "contact",
|
|
13
|
+
"data": {
|
|
14
|
+
"object": {
|
|
15
|
+
"name": "freelancer_contact",
|
|
16
|
+
"permission": "freelancer_permission",
|
|
17
|
+
"replaceExistName": true
|
|
18
|
+
},
|
|
19
|
+
"description": "Freelance provider contact — reach me for project requirements and delivery milestones",
|
|
20
|
+
"ims": {
|
|
21
|
+
"op": "add",
|
|
22
|
+
"im": [
|
|
23
|
+
{
|
|
24
|
+
"at": "freelancer",
|
|
25
|
+
"description": "Primary provider account"
|
|
26
|
+
}
|
|
27
|
+
]
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"env": {
|
|
31
|
+
"network": "testnet",
|
|
32
|
+
"no_cache": true,
|
|
33
|
+
"confirmed": true
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
"notes": [
|
|
37
|
+
"Bind this Contact to the freelance Service via the service call's 'um' field.",
|
|
38
|
+
"ims.im[].at accepts an account name or a full 0x address."
|
|
39
|
+
]
|
|
40
|
+
}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"tags": ["machine", "insurance", "claim", "workflow", "draft", "12-step"],
|
|
5
5
|
"industry": "insurance",
|
|
6
6
|
"operation_type": "machine",
|
|
7
|
-
"source": "docs/examples/Insurance — adapted to the 12-step plan (DRAFT only, schema-validated)",
|
|
7
|
+
"source": "docs/examples/Insurance — adapted to the 12-step plan (DRAFT only, schema-validated, not chain-verified)",
|
|
8
8
|
"verified": false,
|
|
9
9
|
"network": "testnet",
|
|
10
10
|
"call": {
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"tags": ["service", "insurance", "order_allocators", "entity-sharing", "12-step"],
|
|
5
5
|
"industry": "insurance",
|
|
6
6
|
"operation_type": "service",
|
|
7
|
-
"source": "docs/examples/Insurance — adapted to the 12-step plan (allocators only, schema-validated)",
|
|
7
|
+
"source": "docs/examples/Insurance — adapted to the 12-step plan (allocators only, schema-validated, not chain-verified)",
|
|
8
8
|
"verified": false,
|
|
9
9
|
"network": "testnet",
|
|
10
10
|
"call": {
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"tags": ["machine", "publish", "freeze", "immutable", "12-step"],
|
|
5
5
|
"industry": "general",
|
|
6
6
|
"operation_type": "machine",
|
|
7
|
-
"source": "12-step deploy plan (Step 6 Machine publish) — schema-validated",
|
|
7
|
+
"source": "12-step deploy plan (Step 6 Machine publish) — schema-validated, not chain-verified",
|
|
8
8
|
"verified": false,
|
|
9
9
|
"network": "testnet",
|
|
10
10
|
"call": {
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"tags": ["service", "rental", "draft", "create", "12-step"],
|
|
5
5
|
"industry": "rental",
|
|
6
6
|
"operation_type": "service",
|
|
7
|
-
"source": "ziroom testnet deployment 2026-07-29 — adapted to the 12-step plan (DRAFT only, schema-validated)",
|
|
7
|
+
"source": "ziroom testnet deployment 2026-07-29 — adapted to the 12-step plan (DRAFT only, schema-validated, not chain-verified)",
|
|
8
8
|
"verified": false,
|
|
9
9
|
"network": "testnet",
|
|
10
10
|
"call": {
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
}
|
|
55
55
|
},
|
|
56
56
|
"notes": [
|
|
57
|
-
"Strict-mode alternative to the broad 'Merkle Root length == 66' Guard (machine_merkle_root_v2). Broad mode trusts submitter honesty; strict mode enforces WHO submitted (
|
|
57
|
+
"Strict-mode alternative to the broad 'Merkle Root length == 66' Guard (machine_merkle_root_v2). Broad mode trusts submitter honesty; strict mode enforces WHO submitted (whoever benefits bears the burden of proof) without verifying message content on-chain.",
|
|
58
58
|
"Schema-verified: CallGuard_DataSchema (guard.ts) — namedNew creation form; table items carry no object_type (output-only); root logic_and returns Bool (allowed root type). logic_as_u256_greater compares first node > all subsequent nodes, so proof.time is listed before order.time.",
|
|
59
59
|
"Query names verified against knowledge/guard-templates.ts (tpl that uses proof.signer/proof.time/order.time): proof.signer (Proof object, Address), proof.time (U64, clock-derived, always > 0), order.time (U64), order.service (Address). context enum is exactly 'Signer' | 'Clock' | 'Guard'.",
|
|
60
60
|
"Proof generation (provider side, off-chain SDK): messenger submitChainProof(env, peerAddress, description) — about_address = the customer, order id embedded in description; returns proofAddress which is later submitted as identifier 0.",
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"tags": ["service", "retail", "ecommerce", "draft", "create", "12-step"],
|
|
5
5
|
"industry": "retail",
|
|
6
6
|
"operation_type": "service",
|
|
7
|
-
"source": "myshop deployment walkthrough (docs/examples/MyShop) — adapted to the 12-step plan + testnet (DRAFT only, schema-validated)",
|
|
7
|
+
"source": "myshop deployment walkthrough (docs/examples/MyShop) — adapted to the 12-step plan + testnet (DRAFT only, schema-validated, not chain-verified)",
|
|
8
8
|
"verified": false,
|
|
9
9
|
"network": "testnet",
|
|
10
10
|
"call": {
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"tags": ["service", "customer_required", "um", "contact", "messenger", "retail", "hard-linkage", "12-step"],
|
|
5
5
|
"industry": "retail",
|
|
6
6
|
"operation_type": "service",
|
|
7
|
-
"source": "adapted to the 12-step plan + SDK customer_required⟶um hard linkage (schema-validated)",
|
|
7
|
+
"source": "adapted to the 12-step plan + SDK customer_required⟶um hard linkage (schema-validated, not chain-verified)",
|
|
8
8
|
"verified": false,
|
|
9
9
|
"network": "testnet",
|
|
10
10
|
"call": {
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"title": "Create Subscription Contact Object",
|
|
3
|
+
"description": "Create a named Contact object for a subscription service, with a Permission reference and an IM entry pointing at the support account",
|
|
4
|
+
"tags": ["contact", "messenger", "ims", "subscription"],
|
|
5
|
+
"industry": "subscription",
|
|
6
|
+
"operation_type": "contact",
|
|
7
|
+
"source": "Template-generated from K2 industry defaults (not chain-verified)",
|
|
8
|
+
"verified": false,
|
|
9
|
+
"network": "testnet",
|
|
10
|
+
"call": {
|
|
11
|
+
"tool": "onchain_operations",
|
|
12
|
+
"operation_type": "contact",
|
|
13
|
+
"data": {
|
|
14
|
+
"object": {
|
|
15
|
+
"name": "subscription_contact",
|
|
16
|
+
"permission": "subscription_permission",
|
|
17
|
+
"replaceExistName": true
|
|
18
|
+
},
|
|
19
|
+
"description": "Subscription support contact — manage your plan, pause, or cancel anytime",
|
|
20
|
+
"ims": {
|
|
21
|
+
"op": "add",
|
|
22
|
+
"im": [
|
|
23
|
+
{
|
|
24
|
+
"at": "subscription_support",
|
|
25
|
+
"description": "Primary support account"
|
|
26
|
+
}
|
|
27
|
+
]
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"env": {
|
|
31
|
+
"network": "testnet",
|
|
32
|
+
"no_cache": true,
|
|
33
|
+
"confirmed": true
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
"notes": [
|
|
37
|
+
"Bind this Contact to the subscription Service via the service call's 'um' field.",
|
|
38
|
+
"Subscription billing should use charge_guard_signer (explicit user signature per period)."
|
|
39
|
+
]
|
|
40
|
+
}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"tags": ["machine", "multisig", "signature", "approval-gate", "permissionIndex", "draft", "12-step"],
|
|
5
5
|
"industry": "general",
|
|
6
6
|
"operation_type": "machine",
|
|
7
|
-
"source": "docs/examples/ThreeBody_Signature — adapted to the 12-step plan (DRAFT only, schema-validated)",
|
|
7
|
+
"source": "docs/examples/ThreeBody_Signature — adapted to the 12-step plan (DRAFT only, schema-validated, not chain-verified)",
|
|
8
8
|
"verified": false,
|
|
9
9
|
"network": "testnet",
|
|
10
10
|
"call": {
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"tags": ["machine", "travel", "workflow", "forward-guard", "multi-node", "draft", "12-step"],
|
|
5
5
|
"industry": "travel",
|
|
6
6
|
"operation_type": "machine",
|
|
7
|
-
"source": "docs/examples/Travel — adapted to the 12-step plan (DRAFT only, schema-validated)",
|
|
7
|
+
"source": "docs/examples/Travel — adapted to the 12-step plan (DRAFT only, schema-validated, not chain-verified)",
|
|
8
8
|
"verified": false,
|
|
9
9
|
"network": "testnet",
|
|
10
10
|
"call": {
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"tags": ["service", "travel", "draft", "create", "12-step"],
|
|
5
5
|
"industry": "travel",
|
|
6
6
|
"operation_type": "service",
|
|
7
|
-
"source": "docs/examples/Travel — adapted to the 12-step plan (DRAFT only, schema-validated)",
|
|
7
|
+
"source": "docs/examples/Travel — adapted to the 12-step plan (DRAFT only, schema-validated, not chain-verified)",
|
|
8
8
|
"verified": false,
|
|
9
9
|
"network": "testnet",
|
|
10
10
|
"call": {
|
package/dist/harness/plan.js
CHANGED
|
@@ -42,8 +42,8 @@ export const SCENARIO_REGISTRY = [
|
|
|
42
42
|
],
|
|
43
43
|
},
|
|
44
44
|
{
|
|
45
|
-
name: "
|
|
46
|
-
keywords: ["digital", "download", "ebook", "software", "license", "instant", "content"],
|
|
45
|
+
name: "retail",
|
|
46
|
+
keywords: ["retail", "shop", "store", "ecommerce", "buy", "sell", "product", "digital", "download", "ebook", "software", "license", "instant", "content"],
|
|
47
47
|
description: "Instant digital delivery: publish → buy → instant delivery",
|
|
48
48
|
default_permissions: { provider: 1000, customer: "namedOperator" },
|
|
49
49
|
objects: [
|
|
@@ -60,7 +60,7 @@ export const SCENARIO_REGISTRY = [
|
|
|
60
60
|
],
|
|
61
61
|
},
|
|
62
62
|
{
|
|
63
|
-
name: "
|
|
63
|
+
name: "travel",
|
|
64
64
|
keywords: ["travel", "tour", "trip", "package", "booking", "itinerary", "vacation", "hotel"],
|
|
65
65
|
description: "Multi-stage service with milestones: publish → book → itinerary → complete",
|
|
66
66
|
default_permissions: { provider: 1000, customer: "namedOperator", arbiter: 1500 },
|
|
@@ -79,6 +79,45 @@ export const SCENARIO_REGISTRY = [
|
|
|
79
79
|
{ name: "Publish", object_types: ["Service"] },
|
|
80
80
|
],
|
|
81
81
|
},
|
|
82
|
+
{
|
|
83
|
+
name: "education",
|
|
84
|
+
keywords: ["education", "course", "training", "tutor", "teach", "learn", "school", "coach", "class", "lesson"],
|
|
85
|
+
description: "Long-cycle education with milestones: publish → enroll → teach → complete → certificate",
|
|
86
|
+
default_permissions: { provider: 1000, customer: "namedOperator", arbiter: 1500 },
|
|
87
|
+
objects: [
|
|
88
|
+
{ type: "Permission", reversible: true, dependencies: [], user_decisions: ["reuse existing or create new?"], estimated_time: "2min" },
|
|
89
|
+
{ type: "Service", reversible: true, dependencies: ["Permission"], user_decisions: ["name", "course details", "token_type"], estimated_time: "3min" },
|
|
90
|
+
{ type: "Machine", reversible: true, dependencies: ["Service"], user_decisions: ["enrollment states", "milestone flow", "completion"], estimated_time: "15min" },
|
|
91
|
+
{ type: "Guard", reversible: false, dependencies: ["Machine"], user_decisions: ["enrollment guard", "completion guard"], risk_flags: ["immutable_after_creation"], estimated_time: "5min" },
|
|
92
|
+
{ type: "Guard", reversible: false, dependencies: ["Machine"], user_decisions: ["refund guard"], risk_flags: ["immutable_after_creation"], estimated_time: "5min" },
|
|
93
|
+
{ type: "Allocation", reversible: true, dependencies: ["Service", "Guard"], user_decisions: ["milestone payments", "refund policy"], estimated_time: "5min" },
|
|
94
|
+
],
|
|
95
|
+
phases: [
|
|
96
|
+
{ name: "Foundation", object_types: ["Permission", "Service"] },
|
|
97
|
+
{ name: "Business Logic", object_types: ["Machine"] },
|
|
98
|
+
{ name: "Trust Layer", object_types: ["Guard"] },
|
|
99
|
+
{ name: "Revenue", object_types: ["Allocation"] },
|
|
100
|
+
{ name: "Publish", object_types: ["Service"] },
|
|
101
|
+
],
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
name: "subscription",
|
|
105
|
+
keywords: ["subscription", "subscribe", "membership", "recurring", "monthly", "newsletter", "patreon", "tier"],
|
|
106
|
+
description: "Recurring subscription with renewal: publish → subscribe → renew → cancel",
|
|
107
|
+
default_permissions: { provider: 1000, customer: "namedOperator" },
|
|
108
|
+
objects: [
|
|
109
|
+
{ type: "Permission", reversible: true, dependencies: [], estimated_time: "2min" },
|
|
110
|
+
{ type: "Service", reversible: true, dependencies: ["Permission"], user_decisions: ["name", "subscription tiers", "token_type"], estimated_time: "3min" },
|
|
111
|
+
{ type: "Machine", reversible: true, dependencies: ["Service"], user_decisions: ["subscribe states", "renewal flow", "cancellation"], estimated_time: "10min" },
|
|
112
|
+
{ type: "Allocation", reversible: true, dependencies: ["Service"], user_decisions: ["revenue split"], estimated_time: "3min" },
|
|
113
|
+
],
|
|
114
|
+
phases: [
|
|
115
|
+
{ name: "Foundation", object_types: ["Permission", "Service"] },
|
|
116
|
+
{ name: "Business Logic", object_types: ["Machine"] },
|
|
117
|
+
{ name: "Revenue", object_types: ["Allocation"] },
|
|
118
|
+
{ name: "Publish", object_types: ["Service"] },
|
|
119
|
+
],
|
|
120
|
+
},
|
|
82
121
|
{
|
|
83
122
|
name: "general",
|
|
84
123
|
keywords: [],
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function enrichEventsWithObjectText(events: Record<string, unknown>[], network?: string): Promise<Record<string, unknown>[]>;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { query_objects } from "@wowok/wowok";
|
|
2
|
+
const OBJECT_FIELDS = [
|
|
3
|
+
"service",
|
|
4
|
+
"demand",
|
|
5
|
+
"order",
|
|
6
|
+
"progress",
|
|
7
|
+
"arb",
|
|
8
|
+
"arbitration",
|
|
9
|
+
"machine",
|
|
10
|
+
"allocation",
|
|
11
|
+
];
|
|
12
|
+
const TEXT_FIELDS = ["recommend", "feedback", "node", "description"];
|
|
13
|
+
const MAX_OBJECTS_PER_QUERY = 50;
|
|
14
|
+
function hasText(event) {
|
|
15
|
+
return TEXT_FIELDS.some((k) => {
|
|
16
|
+
const v = event[k];
|
|
17
|
+
return typeof v === "string" && v.length > 0;
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
export async function enrichEventsWithObjectText(events, network) {
|
|
21
|
+
const ids = new Set();
|
|
22
|
+
for (const ev of events) {
|
|
23
|
+
if (hasText(ev))
|
|
24
|
+
continue;
|
|
25
|
+
for (const k of OBJECT_FIELDS) {
|
|
26
|
+
const v = ev[k];
|
|
27
|
+
if (typeof v === "string" && v.startsWith("0x"))
|
|
28
|
+
ids.add(v);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
if (ids.size === 0)
|
|
32
|
+
return events;
|
|
33
|
+
const descById = new Map();
|
|
34
|
+
const idList = Array.from(ids);
|
|
35
|
+
for (let i = 0; i < idList.length; i += MAX_OBJECTS_PER_QUERY) {
|
|
36
|
+
const batch = idList.slice(i, i + MAX_OBJECTS_PER_QUERY);
|
|
37
|
+
try {
|
|
38
|
+
const res = await query_objects({ objects: batch, no_cache: false, network });
|
|
39
|
+
const objects = res?.objects ?? [];
|
|
40
|
+
for (const obj of objects) {
|
|
41
|
+
const id = obj?.object;
|
|
42
|
+
const desc = obj?.description;
|
|
43
|
+
if (typeof id === "string" && typeof desc === "string" && desc) {
|
|
44
|
+
descById.set(id, desc);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
if (descById.size === 0)
|
|
52
|
+
return events;
|
|
53
|
+
return events.map((ev) => {
|
|
54
|
+
if (hasText(ev))
|
|
55
|
+
return ev;
|
|
56
|
+
for (const k of OBJECT_FIELDS) {
|
|
57
|
+
const v = ev[k];
|
|
58
|
+
if (typeof v === "string") {
|
|
59
|
+
const desc = descById.get(v);
|
|
60
|
+
if (desc) {
|
|
61
|
+
return { ...ev, _enriched_description: desc, description: desc };
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return ev;
|
|
66
|
+
});
|
|
67
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { IntentMatchResult, IntentRecord, IntentTargetType } from "./types.js";
|
|
2
|
+
import { ALL_INTENT_TARGET_TYPES } from "./types.js";
|
|
3
|
+
import type { IndustryScenario } from "../evaluation/capability.js";
|
|
4
|
+
import type { PersonaRole } from "../persona/types.js";
|
|
5
|
+
export { newIntentId, getIntentStore, setIntentStore, SqliteIntentRadarStore, type IntentRadarStore } from "./store.js";
|
|
6
|
+
export { matchEventsToIntents } from "./matcher.js";
|
|
7
|
+
export { ALL_INTENT_TARGET_TYPES, INTENT_MAX_PER_SCOPE, type IntentRecord, type IntentTargetType, type IntentMatchResult, type IntentEventHit } from "./types.js";
|
|
8
|
+
export declare function resolveIntentSignals(intentText: string): {
|
|
9
|
+
industries: IndustryScenario[];
|
|
10
|
+
keywords: string[];
|
|
11
|
+
};
|
|
12
|
+
export interface CreateIntentInput {
|
|
13
|
+
intent: string;
|
|
14
|
+
account?: string;
|
|
15
|
+
role?: PersonaRole;
|
|
16
|
+
target_types?: IntentTargetType[];
|
|
17
|
+
}
|
|
18
|
+
export declare function createIntent(input: CreateIntentInput): Promise<IntentRecord>;
|
|
19
|
+
export declare function listIntents(account?: string): Promise<IntentRecord[]>;
|
|
20
|
+
export declare function removeIntent(id: string): Promise<boolean>;
|
|
21
|
+
export declare function matchIntent(intentId: string, events: Record<string, unknown>[]): Promise<IntentMatchResult | null>;
|
|
22
|
+
export declare function matchAllIntents(events: Record<string, unknown>[], account?: string): Promise<IntentMatchResult[]>;
|
|
23
|
+
export { ALL_INTENT_TARGET_TYPES as SUPPORTED_TARGET_TYPES };
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { findSimilarIndustries, inferTraitsFromDescription } from "../knowledge/industry-generalizer.js";
|
|
2
|
+
import { matchEventsToIntents } from "./matcher.js";
|
|
3
|
+
import { getIntentStore, newIntentId } from "./store.js";
|
|
4
|
+
import { ALL_INTENT_TARGET_TYPES, INTENT_MAX_PER_SCOPE } from "./types.js";
|
|
5
|
+
export { newIntentId, getIntentStore, setIntentStore, SqliteIntentRadarStore } from "./store.js";
|
|
6
|
+
export { matchEventsToIntents } from "./matcher.js";
|
|
7
|
+
export { ALL_INTENT_TARGET_TYPES, INTENT_MAX_PER_SCOPE } from "./types.js";
|
|
8
|
+
export function resolveIntentSignals(intentText) {
|
|
9
|
+
const text = intentText?.trim();
|
|
10
|
+
if (!text)
|
|
11
|
+
return { industries: [], keywords: [] };
|
|
12
|
+
const { traits, matched_keywords } = inferTraitsFromDescription(text);
|
|
13
|
+
if (matched_keywords.length === 0)
|
|
14
|
+
return { industries: [], keywords: [] };
|
|
15
|
+
const similar = findSimilarIndustries(traits, 3);
|
|
16
|
+
const industries = similar
|
|
17
|
+
.slice(0, 3)
|
|
18
|
+
.map((s) => s.industry)
|
|
19
|
+
.filter((i) => i && i !== "general");
|
|
20
|
+
return { industries, keywords: matched_keywords };
|
|
21
|
+
}
|
|
22
|
+
export async function createIntent(input) {
|
|
23
|
+
const signals = resolveIntentSignals(input.intent);
|
|
24
|
+
const store = getIntentStore();
|
|
25
|
+
const existing = await store.list(input.account);
|
|
26
|
+
if (existing.length >= INTENT_MAX_PER_SCOPE) {
|
|
27
|
+
throw new Error(`intent limit reached (${INTENT_MAX_PER_SCOPE}) for scope ${input.account ?? "system"}`);
|
|
28
|
+
}
|
|
29
|
+
const now = Date.now();
|
|
30
|
+
const record = {
|
|
31
|
+
id: newIntentId(),
|
|
32
|
+
intent: input.intent,
|
|
33
|
+
account: input.account,
|
|
34
|
+
role: input.role,
|
|
35
|
+
industries: signals.industries,
|
|
36
|
+
keywords: signals.keywords,
|
|
37
|
+
target_types: input.target_types ?? [],
|
|
38
|
+
created_at: now,
|
|
39
|
+
updated_at: now,
|
|
40
|
+
};
|
|
41
|
+
await store.save(record);
|
|
42
|
+
return record;
|
|
43
|
+
}
|
|
44
|
+
export async function listIntents(account) {
|
|
45
|
+
return getIntentStore().list(account);
|
|
46
|
+
}
|
|
47
|
+
export async function removeIntent(id) {
|
|
48
|
+
return getIntentStore().remove(id);
|
|
49
|
+
}
|
|
50
|
+
export async function matchIntent(intentId, events) {
|
|
51
|
+
const intent = await getIntentStore().get(intentId);
|
|
52
|
+
if (!intent)
|
|
53
|
+
return null;
|
|
54
|
+
return matchEventsToIntents(events, [intent])[0];
|
|
55
|
+
}
|
|
56
|
+
export async function matchAllIntents(events, account) {
|
|
57
|
+
const intents = await getIntentStore().list(account);
|
|
58
|
+
return matchEventsToIntents(events, intents);
|
|
59
|
+
}
|
|
60
|
+
export { ALL_INTENT_TARGET_TYPES as SUPPORTED_TARGET_TYPES };
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { findSimilarIndustries, inferTraitsFromDescription } from "../knowledge/industry-generalizer.js";
|
|
2
|
+
const TEXT_FIELDS = ["recommend", "feedback", "node", "description"];
|
|
3
|
+
const OBJECT_FIELDS = [
|
|
4
|
+
"order", "service", "demand", "progress", "arb", "arbitration",
|
|
5
|
+
"allocation", "discount", "machine", "task", "address", "resource",
|
|
6
|
+
];
|
|
7
|
+
function eventText(event) {
|
|
8
|
+
return TEXT_FIELDS
|
|
9
|
+
.map((k) => event[k])
|
|
10
|
+
.filter((v) => typeof v === "string" && v.length > 0)
|
|
11
|
+
.join(" ");
|
|
12
|
+
}
|
|
13
|
+
function eventSignals(event) {
|
|
14
|
+
const text = eventText(event);
|
|
15
|
+
if (!text)
|
|
16
|
+
return { industries: [], keywords: [] };
|
|
17
|
+
const { traits, matched_keywords } = inferTraitsFromDescription(text);
|
|
18
|
+
if (matched_keywords.length === 0)
|
|
19
|
+
return { industries: [], keywords: [] };
|
|
20
|
+
const similar = findSimilarIndustries(traits, 3);
|
|
21
|
+
return {
|
|
22
|
+
industries: similar.slice(0, 3).map((s) => s.industry),
|
|
23
|
+
keywords: matched_keywords,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
function eventId(event) {
|
|
27
|
+
const id = event.id;
|
|
28
|
+
if (id?.txDigest)
|
|
29
|
+
return `${id.eventSeq ?? ""}:${id.txDigest}`;
|
|
30
|
+
return String(event.id ?? "");
|
|
31
|
+
}
|
|
32
|
+
function relatedObjects(event) {
|
|
33
|
+
const out = new Set();
|
|
34
|
+
for (const k of OBJECT_FIELDS) {
|
|
35
|
+
const v = event[k];
|
|
36
|
+
if (typeof v === "string" && v.startsWith("0x"))
|
|
37
|
+
out.add(v);
|
|
38
|
+
}
|
|
39
|
+
return Array.from(out);
|
|
40
|
+
}
|
|
41
|
+
function eventType(event) {
|
|
42
|
+
return String(event.type ?? event.type_raw ?? "");
|
|
43
|
+
}
|
|
44
|
+
function scoreEvent(event, intent) {
|
|
45
|
+
const sig = eventSignals(event);
|
|
46
|
+
const matchedIndustries = intent.industries.filter((i) => i !== "general" && sig.industries.includes(i));
|
|
47
|
+
const matchedKeywords = intent.keywords.filter((k) => sig.keywords.includes(k));
|
|
48
|
+
const score = Math.min(100, matchedIndustries.length * 40 + matchedKeywords.length * 20);
|
|
49
|
+
if (score === 0)
|
|
50
|
+
return null;
|
|
51
|
+
return {
|
|
52
|
+
event_type: eventType(event),
|
|
53
|
+
event_id: eventId(event),
|
|
54
|
+
related_objects: relatedObjects(event),
|
|
55
|
+
business_meaning: eventType(event),
|
|
56
|
+
score,
|
|
57
|
+
matched_industries: matchedIndustries,
|
|
58
|
+
matched_keywords: matchedKeywords,
|
|
59
|
+
event,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
export function matchEventsToIntents(events, intents) {
|
|
63
|
+
return intents.map((intent) => {
|
|
64
|
+
const hits = [];
|
|
65
|
+
for (const event of events) {
|
|
66
|
+
const type = eventType(event);
|
|
67
|
+
if (intent.target_types.length > 0 && !intent.target_types.includes(type))
|
|
68
|
+
continue;
|
|
69
|
+
const hit = scoreEvent(event, intent);
|
|
70
|
+
if (hit)
|
|
71
|
+
hits.push(hit);
|
|
72
|
+
}
|
|
73
|
+
hits.sort((a, b) => b.score - a.score);
|
|
74
|
+
return {
|
|
75
|
+
intent_id: intent.id,
|
|
76
|
+
intent: intent.intent,
|
|
77
|
+
hits,
|
|
78
|
+
scanned: events.length,
|
|
79
|
+
};
|
|
80
|
+
});
|
|
81
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { SQLiteStorage } from "@wowok/wowok";
|
|
2
|
+
import type { IntentRecord } from "./types.js";
|
|
3
|
+
export interface IntentRadarStore {
|
|
4
|
+
save(record: IntentRecord): Promise<void>;
|
|
5
|
+
get(id: string): Promise<IntentRecord | null>;
|
|
6
|
+
list(account?: string): Promise<IntentRecord[]>;
|
|
7
|
+
remove(id: string): Promise<boolean>;
|
|
8
|
+
}
|
|
9
|
+
export declare function newIntentId(): string;
|
|
10
|
+
export declare class SqliteIntentRadarStore implements IntentRadarStore {
|
|
11
|
+
private readonly kv;
|
|
12
|
+
constructor(kv?: SQLiteStorage);
|
|
13
|
+
save(record: IntentRecord): Promise<void>;
|
|
14
|
+
get(id: string): Promise<IntentRecord | null>;
|
|
15
|
+
list(account?: string): Promise<IntentRecord[]>;
|
|
16
|
+
remove(id: string): Promise<boolean>;
|
|
17
|
+
}
|
|
18
|
+
export declare function getIntentStore(): IntentRadarStore;
|
|
19
|
+
export declare function setIntentStore(store: IntentRadarStore): void;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { SQLiteStorage } from "@wowok/wowok";
|
|
2
|
+
const KEY_PREFIX = "intent_radar:";
|
|
3
|
+
function parse(raw) {
|
|
4
|
+
try {
|
|
5
|
+
return JSON.parse(raw);
|
|
6
|
+
}
|
|
7
|
+
catch {
|
|
8
|
+
return null;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
export function newIntentId() {
|
|
12
|
+
return `ir_${Date.now().toString(36)}${Math.random().toString(36).slice(2, 8)}`;
|
|
13
|
+
}
|
|
14
|
+
export class SqliteIntentRadarStore {
|
|
15
|
+
kv;
|
|
16
|
+
constructor(kv) {
|
|
17
|
+
this.kv = kv ?? new SQLiteStorage();
|
|
18
|
+
}
|
|
19
|
+
async save(record) {
|
|
20
|
+
await this.kv.put(`${KEY_PREFIX}${record.id}`, JSON.stringify(record));
|
|
21
|
+
}
|
|
22
|
+
async get(id) {
|
|
23
|
+
const raw = await this.kv.get(`${KEY_PREFIX}${id}`);
|
|
24
|
+
return raw ? parse(raw) : null;
|
|
25
|
+
}
|
|
26
|
+
async list(account) {
|
|
27
|
+
const rows = await this.kv.list(KEY_PREFIX);
|
|
28
|
+
const out = [];
|
|
29
|
+
for (const { value } of rows) {
|
|
30
|
+
const record = parse(value);
|
|
31
|
+
if (!record)
|
|
32
|
+
continue;
|
|
33
|
+
if (account === undefined || record.account === account) {
|
|
34
|
+
out.push(record);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return out.sort((a, b) => b.updated_at - a.updated_at);
|
|
38
|
+
}
|
|
39
|
+
async remove(id) {
|
|
40
|
+
const key = `${KEY_PREFIX}${id}`;
|
|
41
|
+
const exists = (await this.kv.get(key)) !== undefined;
|
|
42
|
+
if (exists)
|
|
43
|
+
await this.kv.del(key);
|
|
44
|
+
return exists;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
let _store = null;
|
|
48
|
+
export function getIntentStore() {
|
|
49
|
+
if (!_store)
|
|
50
|
+
_store = new SqliteIntentRadarStore();
|
|
51
|
+
return _store;
|
|
52
|
+
}
|
|
53
|
+
export function setIntentStore(store) {
|
|
54
|
+
_store = store;
|
|
55
|
+
}
|