feat(builder)!: agent-registry family keyless - build_* tools, @ts-nocheck dropped, custody allowlist shrinks to 1
Rewrites agent-network.ts as a typed, keyless module: the five custodial
signing tools (vector_register_agent, vector_update_agent,
vector_transfer_agent, vector_deregister_agent, vector_message_agent) are
replaced by unsigned-build equivalents (vector_build_register_agent,
vector_build_update_agent, vector_build_transfer_agent,
vector_build_deregister_agent, vector_build_message_agent) that take no
mnemonic - the 4-call flow is get_address -> build_* -> signer sign ->
submit -> confirm. The two read-only tools (vector_get_agent_profile,
vector_discover_agents) keep identical behavior, description, and schema,
now backed by registry-build.ts's typed helpers (Tasks 2-3) instead of
local duplicated logic.
@ts-nocheck is dropped - the file now typechecks clean under strict mode
(server.tool()'s generic inference did not explode; the TS2589 concern
that originally motivated @ts-nocheck is confirmed dead under zod/v4).
boundary.test.ts: CUSTODIAL_UNTIL_LATER_PR shrinks from
{agent-network.ts, self-improvement.ts} to {self-improvement.ts} - size
pin 2 -> 1, message updated for spec PR 8 (the last remaining family).
tool-inventory.test.ts: EXPECTED_TOOLS updated for the 5 renames,
alphabetical order preserved, count stays 23.
tool-schemas.snapshot.json regenerated; delta verified surgical - exactly
the 5 old names removed and 5 new names added, all other 18 entries
(11 vector.ts + 5 self-improvement + the 2 unchanged read-only agent
tools) byte-identical.
Also fixes a stale cross-reference this rename exposed:
self-improvement.ts's registry-NFT-not-found error told the caller to
"re-register with vector_register_agent", a tool name that no longer
exists post-rename. Updated to vector_build_register_agent. This is the
only reference to the old names left in packages/builder/src outside the
deferred integration test (test/integration/run.test.ts, explicitly
scoped to a later task per progress.md).
One addition beyond the task brief (Task 3 review, M-c context): the
build_deregister_agent troubleshooting copy gets a 4th tip pointing at
registry-build.ts's I-1 error (deregistration needs a plain AP3X-only
UTxO to clear the validator's returned-change floor).
Gates: typecheck 0, unit 350/350, smoke 26/26 (23 tools), auth+rate-limit
12/12, boundary 4/4.
This commit is contained in:
@@ -14,8 +14,7 @@ import { resolve, join, relative } from 'node:path';
|
||||
const SRC_ROOT = resolve(import.meta.dirname!, '../src');
|
||||
const SCRIPTS_ROOT = resolve(import.meta.dirname!, '../scripts');
|
||||
const CUSTODIAL_UNTIL_LATER_PR = new Set([
|
||||
'vector/agent-network.ts', // family 2 — goes keyless in spec PR 7
|
||||
'vector/self-improvement.ts', // family 3 — goes keyless in spec PR 8
|
||||
'vector/self-improvement.ts', // family 3 (governance) — goes keyless in spec PR 8
|
||||
]);
|
||||
// No \b boundaries: this is deliberately a substring match, not a whole-word
|
||||
// one. Word-bounding let `seedPhrase`, `WALLET_SEED` or `bip39x` slip past
|
||||
@@ -70,12 +69,12 @@ describe('builder custody boundary', () => {
|
||||
}
|
||||
});
|
||||
|
||||
// The allowlist may only shrink (PR 7 drops agent-network.ts to reach 1, PR 8
|
||||
// drops self-improvement.ts to reach 0 - see the "goes keyless in spec PR N"
|
||||
// comments above). Pinning the size means any widening is a deliberate,
|
||||
// The allowlist may only shrink (PR 7 dropped agent-network.ts to reach 1,
|
||||
// PR 8 drops self-improvement.ts to reach 0 - see the "goes keyless in spec
|
||||
// PR N" comment above). Pinning the size means any widening is a deliberate,
|
||||
// reviewable number change instead of a silent `.add(...)` slipping through.
|
||||
test('the allowlist may only shrink', () => {
|
||||
assert.equal(CUSTODIAL_UNTIL_LATER_PR.size, 2, 'the custodial allowlist may only shrink - PR 7 takes it to 1 (drop agent-network), PR 8 to 0');
|
||||
assert.equal(CUSTODIAL_UNTIL_LATER_PR.size, 1, 'the custodial allowlist may only shrink - spec PR 8 takes it to 0');
|
||||
});
|
||||
|
||||
// Pins every FORBIDDEN alternative individually against a fixture corpus, so
|
||||
|
||||
@@ -21,27 +21,27 @@ import { startServer, stopServer, ServerContext } from '../setup.ts';
|
||||
const EXPECTED_TOOLS = [
|
||||
'vector_await_transaction',
|
||||
'vector_build_deploy_contract',
|
||||
'vector_build_deregister_agent',
|
||||
'vector_build_interact_contract',
|
||||
'vector_build_message_agent',
|
||||
'vector_build_register_agent',
|
||||
'vector_build_send_apex',
|
||||
'vector_build_send_tokens',
|
||||
'vector_build_transaction',
|
||||
'vector_deregister_agent',
|
||||
'vector_build_transfer_agent',
|
||||
'vector_build_update_agent',
|
||||
'vector_discover_agents',
|
||||
'vector_dry_run',
|
||||
'vector_get_agent_profile',
|
||||
'vector_get_balance',
|
||||
'vector_get_transaction_history',
|
||||
'vector_get_utxos',
|
||||
'vector_message_agent',
|
||||
'vector_register_agent',
|
||||
'vector_self_improvement_analyze_metrics',
|
||||
'vector_self_improvement_browse',
|
||||
'vector_self_improvement_critique',
|
||||
'vector_self_improvement_endorse',
|
||||
'vector_self_improvement_submit_proposal',
|
||||
'vector_submit_transaction',
|
||||
'vector_transfer_agent',
|
||||
'vector_update_agent',
|
||||
];
|
||||
|
||||
/**
|
||||
|
||||
@@ -60,6 +60,27 @@
|
||||
"$schema": "http://json-schema.org/draft-07/schema#"
|
||||
}
|
||||
},
|
||||
"vector_build_deregister_agent": {
|
||||
"description": "Build an UNSIGNED transaction that deregisters an agent (burns the identity NFT, returns the 10 AP3X deposit to the owner wallet). Takes no key material. Sign locally with vector_signer_sign, broadcast with vector_submit_transaction, then confirm with vector_await_transaction.",
|
||||
"inputSchema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"changeAddress": {
|
||||
"description": "The agent OWNER's wallet address (receives the returned deposit). Get it from vector_signer_get_address.",
|
||||
"type": "string"
|
||||
},
|
||||
"agent_id": {
|
||||
"description": "Agent DID to deregister: did:vector:agent:{policyId}:{nftAssetName}",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"changeAddress",
|
||||
"agent_id"
|
||||
],
|
||||
"$schema": "http://json-schema.org/draft-07/schema#"
|
||||
}
|
||||
},
|
||||
"vector_build_interact_contract": {
|
||||
"description": "Build an UNSIGNED transaction interacting with a deployed Plutus/Aiken contract - lock AP3X at it or spend from it. Takes no key material - sign with your local signer, then broadcast with vector_submit_transaction and confirm with vector_await_transaction.",
|
||||
"inputSchema": {
|
||||
@@ -138,6 +159,90 @@
|
||||
"$schema": "http://json-schema.org/draft-07/schema#"
|
||||
}
|
||||
},
|
||||
"vector_build_message_agent": {
|
||||
"description": "Build an UNSIGNED transaction that sends an on-chain message to a registered agent via TX metadata (label 674), delivering 2 AP3X to the agent's owner address. Takes no key material. Sign locally with vector_signer_sign, broadcast with vector_submit_transaction, then confirm with vector_await_transaction.",
|
||||
"inputSchema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"changeAddress": {
|
||||
"description": "Your wallet address (pays the 2 AP3X delivery and fee; recorded as the sender). Get it from vector_signer_get_address.",
|
||||
"type": "string"
|
||||
},
|
||||
"agent_id": {
|
||||
"description": "Recipient agent DID: did:vector:agent:{policyId}:{nftAssetName}",
|
||||
"type": "string"
|
||||
},
|
||||
"message_type": {
|
||||
"description": "Type of message",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"inquiry",
|
||||
"proposal",
|
||||
"result"
|
||||
]
|
||||
},
|
||||
"payload": {
|
||||
"description": "Message payload (string, max 512 chars)",
|
||||
"type": "string",
|
||||
"maxLength": 512
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"changeAddress",
|
||||
"agent_id",
|
||||
"message_type",
|
||||
"payload"
|
||||
],
|
||||
"$schema": "http://json-schema.org/draft-07/schema#"
|
||||
}
|
||||
},
|
||||
"vector_build_register_agent": {
|
||||
"description": "Build an UNSIGNED transaction that registers an agent in the Vector on-chain registry (mints a soulbound identity NFT, locks a 10 AP3X deposit). Takes no key material. Sign locally with vector_signer_sign, broadcast with vector_submit_transaction, then confirm with vector_await_transaction.",
|
||||
"inputSchema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"changeAddress": {
|
||||
"description": "Your wallet address (source of the deposit and change). Get it from vector_signer_get_address.",
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"description": "Agent name (e.g. 'TradingBot', 'ResearchAgent')",
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 64
|
||||
},
|
||||
"description": {
|
||||
"description": "Short description of the agent's purpose",
|
||||
"type": "string",
|
||||
"maxLength": 256
|
||||
},
|
||||
"capabilities": {
|
||||
"description": "List of capability tags (e.g. ['investing', 'research', 'environmental'])",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"framework": {
|
||||
"description": "Framework used (e.g. 'OpenClaw', 'LangChain', 'CrewAI', 'custom')",
|
||||
"type": "string"
|
||||
},
|
||||
"endpoint": {
|
||||
"description": "A2A communication endpoint URL (or empty string if not applicable)",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"changeAddress",
|
||||
"name",
|
||||
"description",
|
||||
"capabilities",
|
||||
"framework",
|
||||
"endpoint"
|
||||
],
|
||||
"$schema": "http://json-schema.org/draft-07/schema#"
|
||||
}
|
||||
},
|
||||
"vector_build_send_apex": {
|
||||
"description": "Build an UNSIGNED transaction sending AP3X to a recipient. Takes no key material - sign the returned CBOR with your local signer (vector_signer_sign), then broadcast with vector_submit_transaction and confirm with vector_await_transaction.",
|
||||
"inputSchema": {
|
||||
@@ -262,22 +367,74 @@
|
||||
"$schema": "http://json-schema.org/draft-07/schema#"
|
||||
}
|
||||
},
|
||||
"vector_deregister_agent": {
|
||||
"description": "Deregister an agent from the Vector registry. Burns the identity NFT and returns the 10 AP3X deposit to your wallet.",
|
||||
"vector_build_transfer_agent": {
|
||||
"description": "Build an UNSIGNED transaction that transfers agent ownership to a new address (must be a verification-key address, not a script). Takes no key material. Sign locally with vector_signer_sign, broadcast with vector_submit_transaction, then confirm with vector_await_transaction.",
|
||||
"inputSchema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"mnemonic": {
|
||||
"description": "15 or 24-word BIP39 mnemonic for the agent's owner wallet",
|
||||
"changeAddress": {
|
||||
"description": "The CURRENT owner's wallet address. Get it from vector_signer_get_address.",
|
||||
"type": "string"
|
||||
},
|
||||
"agent_id": {
|
||||
"description": "Agent DID to deregister: did:vector:agent:{policyId}:{nftAssetName}",
|
||||
"description": "Agent DID to transfer: did:vector:agent:{policyId}:{nftAssetName}",
|
||||
"type": "string"
|
||||
},
|
||||
"new_owner_address": {
|
||||
"description": "Bech32 address of the new owner (must be a verification key address, not a script address)",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"mnemonic",
|
||||
"changeAddress",
|
||||
"agent_id",
|
||||
"new_owner_address"
|
||||
],
|
||||
"$schema": "http://json-schema.org/draft-07/schema#"
|
||||
}
|
||||
},
|
||||
"vector_build_update_agent": {
|
||||
"description": "Build an UNSIGNED transaction that updates a registered agent's profile fields. Only the specified fields change; others are preserved. Takes no key material - the on-chain validator requires the owner's signature, which you add locally with vector_signer_sign before vector_submit_transaction, then confirm with vector_await_transaction.",
|
||||
"inputSchema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"changeAddress": {
|
||||
"description": "The agent OWNER's wallet address. Get it from vector_signer_get_address.",
|
||||
"type": "string"
|
||||
},
|
||||
"agent_id": {
|
||||
"description": "Agent DID to update: did:vector:agent:{policyId}:{nftAssetName}",
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"description": "New agent name",
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 64
|
||||
},
|
||||
"description": {
|
||||
"description": "New description",
|
||||
"type": "string",
|
||||
"maxLength": 256
|
||||
},
|
||||
"capabilities": {
|
||||
"description": "New capability tags (replaces existing list)",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"framework": {
|
||||
"description": "New framework identifier",
|
||||
"type": "string"
|
||||
},
|
||||
"endpoint": {
|
||||
"description": "New A2A endpoint URL (or empty string to clear)",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"changeAddress",
|
||||
"agent_id"
|
||||
],
|
||||
"$schema": "http://json-schema.org/draft-07/schema#"
|
||||
@@ -431,90 +588,6 @@
|
||||
"$schema": "http://json-schema.org/draft-07/schema#"
|
||||
}
|
||||
},
|
||||
"vector_message_agent": {
|
||||
"description": "Send an on-chain message to a registered Vector agent via TX metadata (label 674). Delivers 2 AP3X to the agent's owner address.",
|
||||
"inputSchema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"agent_id": {
|
||||
"description": "Recipient agent DID: did:vector:agent:{policyId}:{nftAssetName}",
|
||||
"type": "string"
|
||||
},
|
||||
"message_type": {
|
||||
"description": "Type of message",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"inquiry",
|
||||
"proposal",
|
||||
"result"
|
||||
]
|
||||
},
|
||||
"payload": {
|
||||
"description": "Message payload (string, max 512 chars)",
|
||||
"type": "string",
|
||||
"maxLength": 512
|
||||
},
|
||||
"mnemonic": {
|
||||
"description": "15 or 24-word BIP39 mnemonic for the sending wallet",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"agent_id",
|
||||
"message_type",
|
||||
"payload",
|
||||
"mnemonic"
|
||||
],
|
||||
"$schema": "http://json-schema.org/draft-07/schema#"
|
||||
}
|
||||
},
|
||||
"vector_register_agent": {
|
||||
"description": "Register an agent in the Vector on-chain agent registry. Mints a soulbound identity NFT and locks a 10 AP3X deposit.",
|
||||
"inputSchema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"mnemonic": {
|
||||
"description": "15 or 24-word BIP39 mnemonic for the registering wallet",
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"description": "Agent name (e.g. 'TradingBot', 'ResearchAgent')",
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 64
|
||||
},
|
||||
"description": {
|
||||
"description": "Short description of the agent's purpose",
|
||||
"type": "string",
|
||||
"maxLength": 256
|
||||
},
|
||||
"capabilities": {
|
||||
"description": "List of capability tags (e.g. ['investing', 'research', 'environmental'])",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"framework": {
|
||||
"description": "Framework used (e.g. 'OpenClaw', 'LangChain', 'CrewAI', 'custom')",
|
||||
"type": "string"
|
||||
},
|
||||
"endpoint": {
|
||||
"description": "A2A communication endpoint URL (or empty string if not applicable)",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"mnemonic",
|
||||
"name",
|
||||
"description",
|
||||
"capabilities",
|
||||
"framework",
|
||||
"endpoint"
|
||||
],
|
||||
"$schema": "http://json-schema.org/draft-07/schema#"
|
||||
}
|
||||
},
|
||||
"vector_self_improvement_analyze_metrics": {
|
||||
"description": "Analyze proposal metrics: proposal activity, adoption rate, treasury health, and engagement statistics. Read-only - no mnemonic needed.",
|
||||
"inputSchema": {
|
||||
@@ -771,78 +844,5 @@
|
||||
],
|
||||
"$schema": "http://json-schema.org/draft-07/schema#"
|
||||
}
|
||||
},
|
||||
"vector_transfer_agent": {
|
||||
"description": "Transfer agent ownership to a new address. The new owner must have a verification key credential (not a script address).",
|
||||
"inputSchema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"mnemonic": {
|
||||
"description": "15 or 24-word BIP39 mnemonic for the current owner's wallet",
|
||||
"type": "string"
|
||||
},
|
||||
"agent_id": {
|
||||
"description": "Agent DID to transfer: did:vector:agent:{policyId}:{nftAssetName}",
|
||||
"type": "string"
|
||||
},
|
||||
"new_owner_address": {
|
||||
"description": "Bech32 address of the new owner (must be a verification key address, not a script address)",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"mnemonic",
|
||||
"agent_id",
|
||||
"new_owner_address"
|
||||
],
|
||||
"$schema": "http://json-schema.org/draft-07/schema#"
|
||||
}
|
||||
},
|
||||
"vector_update_agent": {
|
||||
"description": "Update a registered agent's profile fields (name, description, capabilities, framework, endpoint). Only the specified fields are changed; others are preserved.",
|
||||
"inputSchema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"mnemonic": {
|
||||
"description": "15 or 24-word BIP39 mnemonic for the agent's owner wallet",
|
||||
"type": "string"
|
||||
},
|
||||
"agent_id": {
|
||||
"description": "Agent DID to update: did:vector:agent:{policyId}:{nftAssetName}",
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"description": "New agent name",
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 64
|
||||
},
|
||||
"description": {
|
||||
"description": "New description",
|
||||
"type": "string",
|
||||
"maxLength": 256
|
||||
},
|
||||
"capabilities": {
|
||||
"description": "New capability tags (replaces existing list)",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"framework": {
|
||||
"description": "New framework identifier",
|
||||
"type": "string"
|
||||
},
|
||||
"endpoint": {
|
||||
"description": "New A2A endpoint URL (or empty string to clear)",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"mnemonic",
|
||||
"agent_id"
|
||||
],
|
||||
"$schema": "http://json-schema.org/draft-07/schema#"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user