@wowok/agent-mcp 2.6.8 → 2.6.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/customer/customer-advice.js +1 -0
- package/dist/customer/info-puzzle.js +1 -0
- package/dist/customer/reminder-system.d.ts +1 -0
- package/dist/customer/reminder-system.js +20 -0
- package/dist/customer/types.d.ts +1 -0
- package/dist/examples/{insurance-machine-create-publish.json → insurance-machine-create.json} +9 -9
- package/dist/examples/insurance-service-allocators.json +55 -0
- package/dist/examples/machine-publish.json +30 -0
- package/dist/examples/rental-ziroom-service-create.json +12 -64
- package/dist/examples/retail-myshop-service-create.json +14 -64
- package/dist/examples/retail-myshop-service-customer-required.json +31 -0
- package/dist/examples/threebody-machine-create.json +9 -10
- package/dist/examples/threebody-service-allocators.json +3 -4
- package/dist/examples/travel-machine-create.json +9 -10
- package/dist/examples/travel-service-create.json +11 -79
- package/dist/harness/index.d.ts +6 -1
- package/dist/harness/index.js +4 -1
- package/dist/harness/plan.d.ts +13 -0
- package/dist/harness/plan.js +24 -0
- package/dist/harness/recover.js +2 -2
- package/dist/index.js +10 -0
- package/dist/project/context-assembly.d.ts +9 -0
- package/dist/project/context-assembly.js +122 -6
- package/dist/project/graph-builder.d.ts +6 -1
- package/dist/project/graph-builder.js +1 -1
- package/dist/project/handlers.d.ts +1 -0
- package/dist/project/handlers.js +22 -9
- package/dist/schema/call/allocation.js +1 -1
- package/dist/schema/call/payment.d.ts +11 -11
- package/dist/schema/call/payment.js +5 -3
- package/dist/schema/call/semantic.js +10 -1
- package/dist/schema/call/service.d.ts +6 -6
- package/dist/schema/call/service.js +14 -3
- package/dist/schema/operations.d.ts +11 -11
- package/dist/schema/project/index.d.ts +105 -0
- package/dist/schema/project/index.js +53 -0
- package/dist/schema/query/index.d.ts +571 -0
- package/dist/schema/query/index.js +42 -1
- package/dist/schema/sync-layer4.js +25 -4
- package/dist/schemas/index.json +1 -1
- package/dist/schemas/onchain_operations.schema.json +7 -8
- package/dist/schemas/onchain_operations_allocation.schema.json +1 -1
- package/dist/schemas/onchain_operations_payment.schema.json +3 -4
- package/dist/schemas/onchain_operations_service.schema.json +3 -3
- package/dist/schemas/project_operation.output.json +79 -0
- package/dist/schemas/project_operation.schema.json +13 -0
- package/dist/schemas/query_toolkit.output.json +39 -1
- package/dist/schemas/wowok_buildin_info.output.json +132 -0
- package/dist/schemas/wowok_buildin_info.schema.json +14 -0
- package/dist/tools/handlers/onchain.js +94 -4
- package/dist/tools/index.js +3 -3
- package/package.json +2 -2
- package/dist/examples/insurance-service-allocators-publish.json +0 -56
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
|
-
"title": "Create
|
|
3
|
-
"description": "
|
|
4
|
-
"tags": ["service", "travel", "
|
|
2
|
+
"title": "Create Travel Service DRAFT (Iceland)",
|
|
3
|
+
"description": "Step 3 of the 12-step deploy plan: create the Iceland travel Service object in DRAFT (unpublished) with only its identity — name, permission, and description. Machine binding, sales (WIP), Arbitration binding, order_allocators (tiered waterfall), and publish are each separate later steps and are intentionally NOT bundled here.",
|
|
4
|
+
"tags": ["service", "travel", "draft", "create", "12-step"],
|
|
5
5
|
"industry": "travel",
|
|
6
6
|
"operation_type": "service",
|
|
7
|
-
"source": "docs/examples/Travel —
|
|
7
|
+
"source": "docs/examples/Travel — adapted to the 12-step plan (DRAFT only, schema-validated)",
|
|
8
8
|
"verified": false,
|
|
9
9
|
"network": "testnet",
|
|
10
10
|
"call": {
|
|
@@ -16,87 +16,19 @@
|
|
|
16
16
|
"permission": "travel_permission",
|
|
17
17
|
"replaceExistName": true
|
|
18
18
|
},
|
|
19
|
-
"description": "Iceland travel service: Blue Lagoon SPA + Glacier Ice Scooting."
|
|
20
|
-
"machine": "travel_machine",
|
|
21
|
-
"sales": {
|
|
22
|
-
"op": "add",
|
|
23
|
-
"sales": [
|
|
24
|
-
{
|
|
25
|
-
"name": "Iceland Travel Package",
|
|
26
|
-
"price": "500000000",
|
|
27
|
-
"stock": "99",
|
|
28
|
-
"suspension": false,
|
|
29
|
-
"wip": "",
|
|
30
|
-
"wip_hash": ""
|
|
31
|
-
}
|
|
32
|
-
]
|
|
33
|
-
},
|
|
34
|
-
"arbitrations": {
|
|
35
|
-
"op": "add",
|
|
36
|
-
"objects": ["travel_arbitration"]
|
|
37
|
-
},
|
|
38
|
-
"order_allocators": {
|
|
39
|
-
"description": "Travel order revenue allocation based on progress state",
|
|
40
|
-
"threshold": 0,
|
|
41
|
-
"allocators": [
|
|
42
|
-
{
|
|
43
|
-
"guard": "merchant_victory_guard",
|
|
44
|
-
"sharing": [
|
|
45
|
-
{
|
|
46
|
-
"who": {"Entity": {"name_or_address": "travel_treasury"}},
|
|
47
|
-
"sharing": 10000,
|
|
48
|
-
"mode": "Rate"
|
|
49
|
-
}
|
|
50
|
-
]
|
|
51
|
-
},
|
|
52
|
-
{
|
|
53
|
-
"guard": "no_ice_scooting_guard",
|
|
54
|
-
"sharing": [
|
|
55
|
-
{
|
|
56
|
-
"who": {"Entity": {"name_or_address": "travel_treasury"}},
|
|
57
|
-
"sharing": 8000,
|
|
58
|
-
"mode": "Rate"
|
|
59
|
-
},
|
|
60
|
-
{
|
|
61
|
-
"who": {"GuardIdentifier": 0},
|
|
62
|
-
"sharing": 2000,
|
|
63
|
-
"mode": "Rate"
|
|
64
|
-
}
|
|
65
|
-
]
|
|
66
|
-
},
|
|
67
|
-
{
|
|
68
|
-
"guard": "no_spa_guard",
|
|
69
|
-
"sharing": [
|
|
70
|
-
{
|
|
71
|
-
"who": {"Entity": {"name_or_address": "travel_treasury"}},
|
|
72
|
-
"sharing": 500,
|
|
73
|
-
"mode": "Rate"
|
|
74
|
-
},
|
|
75
|
-
{
|
|
76
|
-
"who": {"GuardIdentifier": 0},
|
|
77
|
-
"sharing": 9500,
|
|
78
|
-
"mode": "Rate"
|
|
79
|
-
}
|
|
80
|
-
]
|
|
81
|
-
}
|
|
82
|
-
]
|
|
83
|
-
},
|
|
84
|
-
"pause": false,
|
|
85
|
-
"publish": true
|
|
19
|
+
"description": "Iceland travel service: Blue Lagoon SPA + Glacier Ice Scooting."
|
|
86
20
|
},
|
|
87
21
|
"env": {
|
|
88
22
|
"account": "travel_provider",
|
|
89
23
|
"network": "testnet",
|
|
90
|
-
"no_cache": true
|
|
91
|
-
"confirmed": true
|
|
24
|
+
"no_cache": true
|
|
92
25
|
}
|
|
93
26
|
},
|
|
94
27
|
"notes": [
|
|
95
|
-
"
|
|
96
|
-
"
|
|
97
|
-
"
|
|
98
|
-
"
|
|
99
|
-
"
|
|
100
|
-
"Desensitization: doc payload already uses generic local-mark names only (travel_provider, travel_service, travel_treasury, travel_arbitration, guard names); no real personal data or raw 0x object addresses present — nothing replaced."
|
|
28
|
+
"12-STEP PLAN alignment: this file is ONE step (Step 3 Service DRAFT). The full order is Account → Permission → Service DRAFT → Machine → Guard → Machine publish → Sales(WIP) → Treasury(optional) → order_allocators → Contact(um) → Arbitration → Service publish. Do NOT bundle machine/sales/arbitrations/order_allocators/publish into the create call.",
|
|
29
|
+
"object uses the OBJECT form of TypedPermissionObjectSchema (type_parameter omitted → WOW default '0x2::wow::WOW'); description is a top-level Service field. No publish:true here — the Service stays unpublished until Step 12.",
|
|
30
|
+
"machine and order_allocators are PERMANENTLY LOCKED once publish=true executes (service.move assert!(!bPublished)) — set them in their own pre-publish steps, not in this DRAFT.",
|
|
31
|
+
"arbitrations binding requires a Permission DIFFERENT from the Service's (E_ARBITRATION_PERMISSION_CONFLICT) — create a dedicated travel_arbitration Permission first, then bind the Arbitration in the Arbitration step (Step 11), not here.",
|
|
32
|
+
"Travel is a PHYSICAL/service scenario; if it declares customer_required, set it together with a Contact bound as um (hard linkage) in the Contact step."
|
|
101
33
|
]
|
|
102
34
|
}
|
package/dist/harness/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ export * from "./plan.js";
|
|
|
3
3
|
export * from "./verify.js";
|
|
4
4
|
export * from "./recover.js";
|
|
5
5
|
export * from "./checkpoint.js";
|
|
6
|
-
import type { DecisionPoint } from "./plan.js";
|
|
6
|
+
import type { DecisionPoint, MigrationDecision } from "./plan.js";
|
|
7
7
|
import type { VerifyInput } from "./verify.js";
|
|
8
8
|
import type { ODG, ExpectedResult, VerifyReport, RecoveryAction, Checkpoint } from "./types.js";
|
|
9
9
|
export declare class Harness {
|
|
@@ -11,6 +11,11 @@ export declare class Harness {
|
|
|
11
11
|
plan(userInput: string, taskId?: string): ODG;
|
|
12
12
|
classifyIntent(userInput: string): import("./plan.js").IntentClassification;
|
|
13
13
|
getDecisions(odg: ODG): DecisionPoint[];
|
|
14
|
+
getMigrationDecisions(options?: {
|
|
15
|
+
from_network?: "testnet";
|
|
16
|
+
to_network?: "mainnet";
|
|
17
|
+
current_payment_token?: string;
|
|
18
|
+
}): MigrationDecision[];
|
|
14
19
|
detectCycles(odg: ODG): string[] | null;
|
|
15
20
|
getScenarioRegistry(): import("./types.js").ScenarioTemplate[];
|
|
16
21
|
expect(operation: string, intent: string, operationType: string, data?: Record<string, unknown>): ExpectedResult;
|
package/dist/harness/index.js
CHANGED
|
@@ -3,7 +3,7 @@ export * from "./plan.js";
|
|
|
3
3
|
export * from "./verify.js";
|
|
4
4
|
export * from "./recover.js";
|
|
5
5
|
export * from "./checkpoint.js";
|
|
6
|
-
import { classifyIntent, generateODG, identifyDecisionPoints, detectCycles, SCENARIO_REGISTRY } from "./plan.js";
|
|
6
|
+
import { classifyIntent, generateODG, identifyDecisionPoints, detectCycles, SCENARIO_REGISTRY, identifyMigrationDecisions } from "./plan.js";
|
|
7
7
|
import { verify, generateExpected } from "./verify.js";
|
|
8
8
|
import { recover, resetAttempts, getBackoffDelay, RECOVERY_RULES } from "./recover.js";
|
|
9
9
|
import { saveCheckpoint, loadLatestCheckpoint, listCheckpoints, listTasks, createCheckpoint } from "./checkpoint.js";
|
|
@@ -18,6 +18,9 @@ export class Harness {
|
|
|
18
18
|
getDecisions(odg) {
|
|
19
19
|
return identifyDecisionPoints(odg);
|
|
20
20
|
}
|
|
21
|
+
getMigrationDecisions(options) {
|
|
22
|
+
return identifyMigrationDecisions(options);
|
|
23
|
+
}
|
|
21
24
|
detectCycles(odg) {
|
|
22
25
|
return detectCycles(odg);
|
|
23
26
|
}
|
package/dist/harness/plan.d.ts
CHANGED
|
@@ -16,3 +16,16 @@ export interface DecisionPoint {
|
|
|
16
16
|
}
|
|
17
17
|
export declare function identifyDecisionPoints(odg: ODG): DecisionPoint[];
|
|
18
18
|
export declare function detectCycles(odg: ODG): string[] | null;
|
|
19
|
+
export interface MigrationDecision {
|
|
20
|
+
round: string;
|
|
21
|
+
question: string;
|
|
22
|
+
options: string[];
|
|
23
|
+
default?: string;
|
|
24
|
+
note?: string;
|
|
25
|
+
}
|
|
26
|
+
export interface MigrationDecisionOptions {
|
|
27
|
+
from_network?: "testnet";
|
|
28
|
+
to_network?: "mainnet";
|
|
29
|
+
current_payment_token?: string;
|
|
30
|
+
}
|
|
31
|
+
export declare function identifyMigrationDecisions(options?: MigrationDecisionOptions): MigrationDecision[];
|
package/dist/harness/plan.js
CHANGED
|
@@ -250,3 +250,27 @@ export function detectCycles(odg) {
|
|
|
250
250
|
}
|
|
251
251
|
return null;
|
|
252
252
|
}
|
|
253
|
+
export function identifyMigrationDecisions(options) {
|
|
254
|
+
const current = options?.current_payment_token ?? "WOW";
|
|
255
|
+
const from = options?.from_network ?? "testnet";
|
|
256
|
+
const to = options?.to_network ?? "mainnet";
|
|
257
|
+
return [
|
|
258
|
+
{
|
|
259
|
+
round: "M1",
|
|
260
|
+
question: `Your project currently uses "${current}" as the payment token on ${from}. ` +
|
|
261
|
+
`When migrating to ${to}, do you want to keep "${current}" or switch to a stablecoin ` +
|
|
262
|
+
`(e.g. USDT, available via the ETH mainnet cross-chain bridge)?`,
|
|
263
|
+
options: [
|
|
264
|
+
`Keep ${current}`,
|
|
265
|
+
"Switch to USDT",
|
|
266
|
+
"Switch to USDC",
|
|
267
|
+
"Other stablecoin",
|
|
268
|
+
],
|
|
269
|
+
default: `Keep ${current}`,
|
|
270
|
+
note: `Testnet recommendation: WOW for all merchant and order testing. ` +
|
|
271
|
+
`Mainnet: USDT and other stablecoins are available via the ETH mainnet cross-chain bridge ` +
|
|
272
|
+
`and are often preferred to avoid price volatility. If switching, the Service / Treasury / ` +
|
|
273
|
+
`Allocation type_parameter must be updated to the stablecoin's WOW type tag before publishing on mainnet.`,
|
|
274
|
+
},
|
|
275
|
+
];
|
|
276
|
+
}
|
package/dist/harness/recover.js
CHANGED
|
@@ -4,8 +4,8 @@ export const RECOVERY_RULES = {
|
|
|
4
4
|
strategy: "claim_faucet",
|
|
5
5
|
max_attempts: 3,
|
|
6
6
|
automation: "semi",
|
|
7
|
-
detail: "1.
|
|
8
|
-
user_prompt: "Insufficient balance for gas or operation.
|
|
7
|
+
detail: "1. Testnet: claim WOW from the faucet 2. Mainnet: transfer ETH/USDT/USDC/WBTC via the ETH mainnet cross-chain bridge (query active EVM account → top up from external wallet → confirm → cross-chain) 3. Mention the WOW airdrop (under construction) 4. Retry original operation",
|
|
8
|
+
user_prompt: "Insufficient balance for gas or operation. How to obtain WOW tokens: (1) Testnet — claim WOW from the faucet (https://faucet.testnet.wowok.net); all merchant and order testing can use WOW as the payment token. (2) Mainnet — transfer ETH / USDT / USDC / WBTC via the ETH mainnet cross-chain bridge: first query the active EVM account (bridge_operation query_active_evm_account, auto-generated on first use), then transfer from an external wallet (e.g. MetaMask) to that address, confirm the balance arrived, and cross-chain to WOW mainnet (bridge_operation cross_chain_evm_to_wow). (3) WOW mainnet airdrop: https://airdrop.wowok.net (under construction).",
|
|
9
9
|
},
|
|
10
10
|
network_error: {
|
|
11
11
|
error_code: "network_error",
|
package/dist/index.js
CHANGED
|
@@ -89,6 +89,16 @@ Read the schema, fix your params, and retry. CACHE the schema in your context fo
|
|
|
89
89
|
|
|
90
90
|
When the current context does not contain a sub-tool's input/output schema, or when you are uncertain whether the schema you have is complete and up-to-date, you MUST query it first before calling the sub-tool. Use \`wowok({ tool: "schema_query", data: { action: "get", name: "<sub-tool>" } })` + "`" + ` for operational sub-tool schemas or \`wowok({ tool: "wowok_buildin_info", data: { info: "..." } })\` for protocol constants and reference data. Never guess schema parameters, query instruction IDs, or type codes — always retrieve them from the live server.
|
|
91
91
|
|
|
92
|
+
## CRITICAL: Global Unread Messenger Check (every conversation)
|
|
93
|
+
|
|
94
|
+
At the START of EVERY conversation — before answering the user's request, regardless of what it is about — check for unread Messenger messages and IMMEDIATELY and PROMINENTLY remind the user to read them:
|
|
95
|
+
|
|
96
|
+
\`\`\`
|
|
97
|
+
wowok({ tool: "messenger_operation", data: { operation: "watch_conversations", filter: { unreadOnly: true, previewMessageCount: 0, skipAutoMarkViewed: true } } })
|
|
98
|
+
\`\`\`
|
|
99
|
+
|
|
100
|
+
If the result contains any conversation with \`unreadCount > 0\`, surface a prominent reminder at the TOP of your response (do not wait for the user to ask), listing each peer with unread messages and the count. Use \`skipAutoMarkViewed: true\` so merely checking does not mark them read. If there are none, do not mention the check.
|
|
101
|
+
|
|
92
102
|
## Token System Overview
|
|
93
103
|
|
|
94
104
|
### Default Platform Token: WOW
|
|
@@ -2,11 +2,20 @@ import type { z } from "zod";
|
|
|
2
2
|
import type { ProjectOperationInputSchema } from "../schema/project/index.js";
|
|
3
3
|
import { type ContextCollectionResult } from "../loop-engineering/context-collect.js";
|
|
4
4
|
type ValidatedInput = z.infer<typeof ProjectOperationInputSchema>;
|
|
5
|
+
export interface DependencyEdge {
|
|
6
|
+
object: string;
|
|
7
|
+
depth: number;
|
|
8
|
+
via_field: string;
|
|
9
|
+
via_type: string;
|
|
10
|
+
parent: string;
|
|
11
|
+
}
|
|
5
12
|
export interface AssembleContextResult {
|
|
6
13
|
action: "assemble_context";
|
|
7
14
|
objects: unknown[];
|
|
8
15
|
events?: unknown[];
|
|
9
16
|
embedded_history?: Record<string, unknown>;
|
|
17
|
+
dependencies?: DependencyEdge[];
|
|
18
|
+
dependency_objects?: unknown[];
|
|
10
19
|
semantic_summary?: unknown;
|
|
11
20
|
context_digest: string;
|
|
12
21
|
next_action: string;
|
|
@@ -3,6 +3,7 @@ import { query_objects, query_events } from "@wowok/wowok";
|
|
|
3
3
|
import { annotateEventsMonetaryFields } from "../knowledge/fund-layer.js";
|
|
4
4
|
import { buildDataSemantic } from "../schema/call/semantic.js";
|
|
5
5
|
import { collectContextExperience } from "../loop-engineering/context-collect.js";
|
|
6
|
+
import { extractAddressFields } from "./graph-builder.js";
|
|
6
7
|
const STATE_TRANSITION_EVENTS = [
|
|
7
8
|
"NewOrderEvent",
|
|
8
9
|
"ProgressEvent",
|
|
@@ -11,6 +12,7 @@ const STATE_TRANSITION_EVENTS = [
|
|
|
11
12
|
"DemandFeedbackEvent",
|
|
12
13
|
"NewEntityEvent",
|
|
13
14
|
];
|
|
15
|
+
const MAX_OBJECTS_PER_QUERY = 50;
|
|
14
16
|
export async function assembleContext(validated) {
|
|
15
17
|
const contextObjects = validated.context_objects;
|
|
16
18
|
if (!contextObjects || contextObjects.length === 0) {
|
|
@@ -18,13 +20,105 @@ export async function assembleContext(validated) {
|
|
|
18
20
|
}
|
|
19
21
|
const network = (validated.context_network ?? "testnet");
|
|
20
22
|
const includeEvents = validated.include_events ?? false;
|
|
23
|
+
const depth = Math.max(0, Math.min(5, validated.context_depth ?? 0));
|
|
24
|
+
const includeFilter = validated.context_include?.length
|
|
25
|
+
? new Set(validated.context_include)
|
|
26
|
+
: null;
|
|
21
27
|
const objectsResult = await query_objects({
|
|
22
28
|
objects: contextObjects,
|
|
23
29
|
no_cache: false,
|
|
24
30
|
network,
|
|
25
31
|
});
|
|
26
32
|
const objects = objectsResult?.objects ?? [];
|
|
27
|
-
const
|
|
33
|
+
const dependencies = [];
|
|
34
|
+
const dependencyObjects = [];
|
|
35
|
+
if (depth > 0) {
|
|
36
|
+
const visited = new Set();
|
|
37
|
+
for (const o of objects) {
|
|
38
|
+
const id = o?.object;
|
|
39
|
+
if (typeof id === "string")
|
|
40
|
+
visited.add(id);
|
|
41
|
+
}
|
|
42
|
+
let frontier = [];
|
|
43
|
+
for (const o of objects) {
|
|
44
|
+
const refs = safeExtractAddressFields(o);
|
|
45
|
+
for (const r of refs) {
|
|
46
|
+
if (includeFilter && !includeFilter.has(r.field))
|
|
47
|
+
continue;
|
|
48
|
+
if (visited.has(r.address))
|
|
49
|
+
continue;
|
|
50
|
+
frontier.push({
|
|
51
|
+
id: r.address,
|
|
52
|
+
parent: o?.object ?? "",
|
|
53
|
+
viaField: r.field,
|
|
54
|
+
viaType: r.type,
|
|
55
|
+
depth: 1,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
for (let currentDepth = 1; currentDepth <= depth && frontier.length > 0; currentDepth++) {
|
|
60
|
+
const seenInLevel = new Set();
|
|
61
|
+
const uniqueFrontier = [];
|
|
62
|
+
for (const f of frontier) {
|
|
63
|
+
if (visited.has(f.id) || seenInLevel.has(f.id))
|
|
64
|
+
continue;
|
|
65
|
+
seenInLevel.add(f.id);
|
|
66
|
+
visited.add(f.id);
|
|
67
|
+
uniqueFrontier.push(f);
|
|
68
|
+
}
|
|
69
|
+
if (uniqueFrontier.length === 0)
|
|
70
|
+
break;
|
|
71
|
+
const nextFrontier = [];
|
|
72
|
+
for (let i = 0; i < uniqueFrontier.length; i += MAX_OBJECTS_PER_QUERY) {
|
|
73
|
+
const batch = uniqueFrontier.slice(i, i + MAX_OBJECTS_PER_QUERY);
|
|
74
|
+
let batchResult;
|
|
75
|
+
try {
|
|
76
|
+
batchResult = await query_objects({
|
|
77
|
+
objects: batch.map((b) => b.id),
|
|
78
|
+
no_cache: false,
|
|
79
|
+
network,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
const batchObjs = batchResult?.objects ?? [];
|
|
86
|
+
for (let j = 0; j < batch.length; j++) {
|
|
87
|
+
const f = batch[j];
|
|
88
|
+
const obj = batchObjs[j];
|
|
89
|
+
if (!obj)
|
|
90
|
+
continue;
|
|
91
|
+
dependencies.push({
|
|
92
|
+
object: f.id,
|
|
93
|
+
depth: f.depth,
|
|
94
|
+
via_field: f.viaField,
|
|
95
|
+
via_type: f.viaType,
|
|
96
|
+
parent: f.parent,
|
|
97
|
+
});
|
|
98
|
+
dependencyObjects.push(obj);
|
|
99
|
+
if (currentDepth < depth) {
|
|
100
|
+
const refs = safeExtractAddressFields(obj);
|
|
101
|
+
for (const r of refs) {
|
|
102
|
+
if (includeFilter && !includeFilter.has(r.field))
|
|
103
|
+
continue;
|
|
104
|
+
if (visited.has(r.address))
|
|
105
|
+
continue;
|
|
106
|
+
nextFrontier.push({
|
|
107
|
+
id: r.address,
|
|
108
|
+
parent: f.id,
|
|
109
|
+
viaField: r.field,
|
|
110
|
+
viaType: r.type,
|
|
111
|
+
depth: currentDepth + 1,
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
frontier = nextFrontier;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
const allObjectsForHistory = [...objects, ...dependencyObjects];
|
|
121
|
+
const embeddedHistory = extractEmbeddedHistory(allObjectsForHistory);
|
|
28
122
|
const hasEmbeddedHistory = Object.keys(embeddedHistory).length > 0;
|
|
29
123
|
let events;
|
|
30
124
|
if (includeEvents) {
|
|
@@ -61,16 +155,26 @@ export async function assembleContext(validated) {
|
|
|
61
155
|
};
|
|
62
156
|
const semanticSummary = buildDataSemantic({ objects, embedded_history: embeddedHistory, events }, semanticCtx);
|
|
63
157
|
const digestParts = objects.map((obj) => `${obj?.object ?? obj?.data?.object ?? "?"}:${obj?.version ?? obj?.data?.version ?? "?"}`);
|
|
158
|
+
if (dependencyObjects.length > 0) {
|
|
159
|
+
digestParts.push(`deps:${dependencyObjects
|
|
160
|
+
.map((o) => `${o?.object ?? "?"}:${o?.version ?? "?"}`)
|
|
161
|
+
.join(",")}`);
|
|
162
|
+
}
|
|
64
163
|
digestParts.push(`ts:${Date.now()}`);
|
|
65
164
|
const contextDigest = createHash("sha256")
|
|
66
165
|
.update(digestParts.join("|"))
|
|
67
166
|
.digest("hex")
|
|
68
167
|
.substring(0, 16);
|
|
69
|
-
const
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
168
|
+
const hasDependencies = dependencies.length > 0;
|
|
169
|
+
const nextAction = hasDependencies
|
|
170
|
+
? `Context assembled with ${dependencies.length} dependency object(s) across ${depth} level(s). ` +
|
|
171
|
+
"Use onchain_transaction with a specific digest to verify a past operation, " +
|
|
172
|
+
"or proceed with onchain_operations (consider dry_run=true first to validate)."
|
|
173
|
+
: hasEmbeddedHistory
|
|
174
|
+
? "Context assembled with embedded operation history. Use onchain_transaction with a specific digest to verify a past operation, or proceed with onchain_operations (consider dry_run=true first to validate)."
|
|
175
|
+
: events && events.length > 0
|
|
176
|
+
? "Context assembled with recent events. Use onchain_transaction with a specific digest to verify any event's tx, or proceed with onchain_operations."
|
|
177
|
+
: "Context assembled (current state only). Proceed with onchain_operations (consider dry_run=true first to validate).";
|
|
74
178
|
let flywheelCollected;
|
|
75
179
|
try {
|
|
76
180
|
flywheelCollected = collectContextExperience({
|
|
@@ -90,12 +194,24 @@ export async function assembleContext(validated) {
|
|
|
90
194
|
objects,
|
|
91
195
|
events,
|
|
92
196
|
embedded_history: hasEmbeddedHistory ? embeddedHistory : undefined,
|
|
197
|
+
dependencies: hasDependencies ? dependencies : undefined,
|
|
198
|
+
dependency_objects: hasDependencies ? dependencyObjects : undefined,
|
|
93
199
|
semantic_summary: semanticSummary,
|
|
94
200
|
context_digest: contextDigest,
|
|
95
201
|
next_action: nextAction,
|
|
96
202
|
flywheel_collected: flywheelCollected,
|
|
97
203
|
};
|
|
98
204
|
}
|
|
205
|
+
function safeExtractAddressFields(obj) {
|
|
206
|
+
if (!obj || typeof obj !== "object")
|
|
207
|
+
return [];
|
|
208
|
+
try {
|
|
209
|
+
return extractAddressFields(obj);
|
|
210
|
+
}
|
|
211
|
+
catch {
|
|
212
|
+
return [];
|
|
213
|
+
}
|
|
214
|
+
}
|
|
99
215
|
function extractEmbeddedHistory(objects) {
|
|
100
216
|
const history = {};
|
|
101
217
|
for (const obj of objects) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type GraphData, type GraphNode } from "@wowok/wowok";
|
|
1
|
+
import { type ObjectBase, type GraphData, type GraphNode } from "@wowok/wowok";
|
|
2
2
|
export type GraphNodeWithTemplate = GraphNode & {
|
|
3
3
|
isTemplate?: boolean;
|
|
4
4
|
};
|
|
@@ -29,6 +29,11 @@ export interface GraphBuildResult {
|
|
|
29
29
|
graph: GraphData;
|
|
30
30
|
reputation: Map<string, ReputationData>;
|
|
31
31
|
}
|
|
32
|
+
export declare function extractAddressFields(obj: ObjectBase): Array<{
|
|
33
|
+
address: string;
|
|
34
|
+
field: string;
|
|
35
|
+
type: string;
|
|
36
|
+
}>;
|
|
32
37
|
export declare class GraphBuilder {
|
|
33
38
|
private localProject;
|
|
34
39
|
private rateLimiter;
|
|
@@ -7,7 +7,7 @@ function shortTypeName(objectType) {
|
|
|
7
7
|
const segments = base.split("::");
|
|
8
8
|
return segments[segments.length - 1] || "unknown";
|
|
9
9
|
}
|
|
10
|
-
function extractAddressFields(obj) {
|
|
10
|
+
export function extractAddressFields(obj) {
|
|
11
11
|
const refs = [];
|
|
12
12
|
const rawType = obj.type;
|
|
13
13
|
let objType = rawType;
|
|
@@ -320,6 +320,7 @@ export declare function handleMigrateToMainnet(v: ProjectInput): Promise<{
|
|
|
320
320
|
cloned_objects_count: number;
|
|
321
321
|
};
|
|
322
322
|
key_principle: string;
|
|
323
|
+
payment_token_decision: import("../harness/plan.js").MigrationDecision;
|
|
323
324
|
migration_plan: ({
|
|
324
325
|
step: number;
|
|
325
326
|
status: string;
|
package/dist/project/handlers.js
CHANGED
|
@@ -8,6 +8,7 @@ import { renderGuardMermaid, renderGuardTreeIndented, renderGuardAscii, renderGu
|
|
|
8
8
|
import { renderMachineMermaid, renderMachineTreeIndented, renderMachineAscii, renderMachineMarkmap, } from "../knowledge/machine-render.js";
|
|
9
9
|
import { inferTraitsFromDescription, findSimilarIndustries, } from "../knowledge/industry-generalizer.js";
|
|
10
10
|
import { isObjectOfType } from "../schema/utils/object-type-utils.js";
|
|
11
|
+
import { identifyMigrationDecisions } from "../harness/plan.js";
|
|
11
12
|
const localProject = LocalProject.Instance();
|
|
12
13
|
function requireField(value, name) {
|
|
13
14
|
if (value === undefined || value === null) {
|
|
@@ -309,14 +310,18 @@ function getRecommendedCreationOrder(industry) {
|
|
|
309
310
|
? ` (industry="${industry}" — see IndustryMode.build_notes for overrides)`
|
|
310
311
|
: "";
|
|
311
312
|
return [
|
|
312
|
-
{ step: 1, object: "
|
|
313
|
-
{ step: 2, object: "
|
|
314
|
-
{ step: 3, object: "
|
|
315
|
-
{ step: 4, object: "
|
|
316
|
-
{ step: 5, object: "
|
|
317
|
-
{ step: 6, object: "
|
|
318
|
-
{ step: 7, object: "
|
|
319
|
-
{ step: 8, object: "
|
|
313
|
+
{ step: 1, object: "Account", reason: "Base identity for on-chain operations; owns all subsequent objects and receives settlement.", required: true },
|
|
314
|
+
{ step: 2, object: "Permission", reason: "Centralized access control; referenced by ALL objects (Service, Machine, Guard, Contact, Arbitration).", required: true },
|
|
315
|
+
{ step: 3, object: "Service (draft)", reason: "Create the skeleton FIRST (unpublished) so Guards can reference it by LocalMark NAME — breaks the Guard↔Service circular dependency.", required: true },
|
|
316
|
+
{ step: 4, object: "Machine (unpublished)", reason: `Business workflow nodes/forwards. Requires Permission.${industryNote}`, required: true },
|
|
317
|
+
{ step: 5, object: "Guard x N", reason: "Acceptance logic referencing machine node names + service name via LocalMark. Bind to Machine forwards before publish.", required: true },
|
|
318
|
+
{ step: 6, object: "Machine publish", reason: "Freeze workflow topology (nodes/pairs/forwards immutable). Export machineNode2file first for backup.", required: true },
|
|
319
|
+
{ step: 7, object: "Sales (WIP)", reason: "Products with wip URL (must be a public endpoint) + wip_hash. Recommend generating WIP from web/doc material via AI sub-task.", required: true },
|
|
320
|
+
{ step: 8, object: "Treasury (optional)", reason: "Fund pool for organizations; referenced by order_allocators as an Entity recipient. Skip for personal merchants.", required: false },
|
|
321
|
+
{ step: 9, object: "order_allocators", reason: "Fund distribution (Amount/Rate/Surplus). Personal merchant → Permission owner; organization → Treasury.", required: true },
|
|
322
|
+
{ step: 10, object: "Contact", reason: "Customer-service channel (Service.um → Contact → ims[]); enable local account as messenger + anti-spam.", required: true },
|
|
323
|
+
{ step: 11, object: "Arbitration (optional)", reason: "Third-party dispute resolution (REUSE an existing Arbitration). MUST NOT reuse Service's Permission — E_ARBITRATION_PERMISSION_CONFLICT. Requires compensation_fund if configured.", required: false },
|
|
324
|
+
{ step: 12, object: "Service publish", reason: "Add machine + order_allocators + buy_guard + sales + arbitrations, then publish:true. machine/order_allocators/arbitrations immutable after publish.", required: true },
|
|
320
325
|
];
|
|
321
326
|
}
|
|
322
327
|
function mapEdgeKindToRelationshipType(edgeKind) {
|
|
@@ -1155,6 +1160,11 @@ export async function handleMigrateToMainnet(v) {
|
|
|
1155
1160
|
"but they correspond to DIFFERENT on-chain addresses. The testnet project is preserved unchanged. " +
|
|
1156
1161
|
"LocalMark names are NETWORK-SCOPED: a name resolves to a testnet address when env.network=testnet, " +
|
|
1157
1162
|
"and to a mainnet address when env.network=mainnet. Register the SAME name TWICE (once per network).",
|
|
1163
|
+
payment_token_decision: identifyMigrationDecisions({
|
|
1164
|
+
from_network: "testnet",
|
|
1165
|
+
to_network: "mainnet",
|
|
1166
|
+
current_payment_token: "WOW",
|
|
1167
|
+
})[0],
|
|
1158
1168
|
migration_plan: [
|
|
1159
1169
|
{
|
|
1160
1170
|
step: 1,
|
|
@@ -1173,7 +1183,10 @@ export async function handleMigrateToMainnet(v) {
|
|
|
1173
1183
|
deployment_plan: deploymentPlan,
|
|
1174
1184
|
critical_note: "Re-deploy in dependency order: Permission → Machine → Contact → Guard(s) → Service. " +
|
|
1175
1185
|
"For the Service↔Guard circular dependency, use the 3-step pattern " +
|
|
1176
|
-
"(Service without order_allocators → Guards → Service with order_allocators + publish)."
|
|
1186
|
+
"(Service without order_allocators → Guards → Service with order_allocators + publish). " +
|
|
1187
|
+
"BEFORE deploying, decide the payment token (see payment_token_decision above): if switching " +
|
|
1188
|
+
"from WOW to a stablecoin (e.g. USDT), set the Service / Treasury / Allocation type_parameter " +
|
|
1189
|
+
"to the stablecoin's WOW type tag (query 'mainnet bridge tokens' via wowok_buildin_info).",
|
|
1177
1190
|
},
|
|
1178
1191
|
{
|
|
1179
1192
|
step: 3,
|
|
@@ -18,7 +18,7 @@ export const CallAllocation_OperateSchema = z.object({
|
|
|
18
18
|
"GuardIdentifier n recipients receive it at the ADDRESS SUBMITTED for identifier n in this call's submission " +
|
|
19
19
|
"(resolved via passport::submission_get) — conventionally the Order OBJECT address (escrow pattern), " +
|
|
20
20
|
"in which case the order owner claims it via operation_type='order' {object:'<order_id>', receive:'recently'}. " +
|
|
21
|
-
"Claim paths by holder: EOA wallet → operation_type='payment' RECEIVE mode {object:'<coinwrapper_id>', receive:true,
|
|
21
|
+
"Claim paths by holder: EOA wallet → operation_type='payment' RECEIVE mode {object:'<coinwrapper_id>', receive:true} (type_parameter optional, auto-derived from the CoinWrapper type); " +
|
|
22
22
|
"Order object → order receive; Treasury object → treasury receive. " +
|
|
23
23
|
"Find pending CoinWrappers via query_toolkit query_type='onchain_received'. " +
|
|
24
24
|
"Verify the distribution via the immutable Payment object created by this call (allocation.payment array).")
|
|
@@ -180,15 +180,15 @@ export declare const CallPayment_CreateSchema: z.ZodObject<{
|
|
|
180
180
|
export declare const CallPayment_ReceiveSchema: z.ZodObject<{
|
|
181
181
|
object: z.ZodEffects<z.ZodString, string, string>;
|
|
182
182
|
receive: z.ZodLiteral<true>;
|
|
183
|
-
type_parameter: z.ZodString
|
|
183
|
+
type_parameter: z.ZodOptional<z.ZodString>;
|
|
184
184
|
}, "strict", z.ZodTypeAny, {
|
|
185
185
|
object: string;
|
|
186
|
-
type_parameter: string;
|
|
187
186
|
receive: true;
|
|
187
|
+
type_parameter?: string | undefined;
|
|
188
188
|
}, {
|
|
189
189
|
object: string;
|
|
190
|
-
type_parameter: string;
|
|
191
190
|
receive: true;
|
|
191
|
+
type_parameter?: string | undefined;
|
|
192
192
|
}>;
|
|
193
193
|
export declare const CallPayment_DataSchema: z.ZodUnion<[z.ZodObject<{
|
|
194
194
|
object: z.ZodObject<{
|
|
@@ -325,15 +325,15 @@ export declare const CallPayment_DataSchema: z.ZodUnion<[z.ZodObject<{
|
|
|
325
325
|
}>, z.ZodObject<{
|
|
326
326
|
object: z.ZodEffects<z.ZodString, string, string>;
|
|
327
327
|
receive: z.ZodLiteral<true>;
|
|
328
|
-
type_parameter: z.ZodString
|
|
328
|
+
type_parameter: z.ZodOptional<z.ZodString>;
|
|
329
329
|
}, "strict", z.ZodTypeAny, {
|
|
330
330
|
object: string;
|
|
331
|
-
type_parameter: string;
|
|
332
331
|
receive: true;
|
|
332
|
+
type_parameter?: string | undefined;
|
|
333
333
|
}, {
|
|
334
334
|
object: string;
|
|
335
|
-
type_parameter: string;
|
|
336
335
|
receive: true;
|
|
336
|
+
type_parameter?: string | undefined;
|
|
337
337
|
}>]>;
|
|
338
338
|
export declare const CallPayment_InputSchema: z.ZodObject<{
|
|
339
339
|
data: z.ZodUnion<[z.ZodObject<{
|
|
@@ -471,15 +471,15 @@ export declare const CallPayment_InputSchema: z.ZodObject<{
|
|
|
471
471
|
}>, z.ZodObject<{
|
|
472
472
|
object: z.ZodEffects<z.ZodString, string, string>;
|
|
473
473
|
receive: z.ZodLiteral<true>;
|
|
474
|
-
type_parameter: z.ZodString
|
|
474
|
+
type_parameter: z.ZodOptional<z.ZodString>;
|
|
475
475
|
}, "strict", z.ZodTypeAny, {
|
|
476
476
|
object: string;
|
|
477
|
-
type_parameter: string;
|
|
478
477
|
receive: true;
|
|
478
|
+
type_parameter?: string | undefined;
|
|
479
479
|
}, {
|
|
480
480
|
object: string;
|
|
481
|
-
type_parameter: string;
|
|
482
481
|
receive: true;
|
|
482
|
+
type_parameter?: string | undefined;
|
|
483
483
|
}>]>;
|
|
484
484
|
env: z.ZodOptional<z.ZodObject<{
|
|
485
485
|
account: z.ZodDefault<z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>>;
|
|
@@ -546,8 +546,8 @@ export declare const CallPayment_InputSchema: z.ZodObject<{
|
|
|
546
546
|
}[];
|
|
547
547
|
} | {
|
|
548
548
|
object: string;
|
|
549
|
-
type_parameter: string;
|
|
550
549
|
receive: true;
|
|
550
|
+
type_parameter?: string | undefined;
|
|
551
551
|
};
|
|
552
552
|
env?: {
|
|
553
553
|
account: string;
|
|
@@ -590,8 +590,8 @@ export declare const CallPayment_InputSchema: z.ZodObject<{
|
|
|
590
590
|
}[];
|
|
591
591
|
} | {
|
|
592
592
|
object: string;
|
|
593
|
-
type_parameter: string;
|
|
594
593
|
receive: true;
|
|
594
|
+
type_parameter?: string | undefined;
|
|
595
595
|
};
|
|
596
596
|
env?: {
|
|
597
597
|
no_cache?: boolean | undefined;
|