@wzrd_sol/eliza-plugin 0.1.2 → 0.3.0
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 +98 -26
- package/dist/actions/claim.d.ts +2 -5
- package/dist/actions/claim.js +33 -30
- package/dist/actions/earn.d.ts +8 -0
- package/dist/actions/earn.js +83 -0
- package/dist/actions/infer.d.ts +8 -0
- package/dist/actions/infer.js +41 -0
- package/dist/actions/intel-preflight.d.ts +5 -0
- package/dist/actions/intel-preflight.js +97 -0
- package/dist/actions/intel-trust.d.ts +7 -0
- package/dist/actions/intel-trust.js +82 -0
- package/dist/actions/report.d.ts +8 -0
- package/dist/actions/report.js +45 -0
- package/dist/actions/rewards.d.ts +5 -0
- package/dist/actions/rewards.js +31 -0
- package/dist/actions/verify-receipt.d.ts +7 -0
- package/dist/actions/verify-receipt.js +44 -0
- package/dist/client-factory.d.ts +14 -0
- package/dist/client-factory.js +40 -0
- package/dist/client.d.ts +91 -3
- package/dist/client.js +136 -16
- package/dist/index.d.ts +26 -9
- package/dist/index.js +25 -9
- package/dist/intel-helpers.d.ts +22 -0
- package/dist/intel-helpers.js +181 -0
- package/dist/paying-fetch.d.ts +9 -0
- package/dist/paying-fetch.js +27 -0
- package/dist/test/plugin-registration.intel.d.ts +1 -0
- package/dist/test/plugin-registration.intel.js +253 -0
- package/package.json +21 -10
- package/dist/actions/deposit.d.ts +0 -2
- package/dist/actions/deposit.js +0 -79
- package/dist/actions/leaderboard.d.ts +0 -3
- package/dist/actions/leaderboard.js +0 -25
- package/dist/actions/portfolio.d.ts +0 -3
- package/dist/actions/portfolio.js +0 -20
- package/dist/actions/velocity.d.ts +0 -3
- package/dist/actions/velocity.js +0 -57
package/README.md
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# @wzrd_sol/eliza-plugin
|
|
2
2
|
|
|
3
|
-
ElizaOS plugin for
|
|
3
|
+
ElizaOS plugin for WZRD Agent Intel and the legacy earn loop on Solana.
|
|
4
|
+
|
|
5
|
+
**Before any x402 spend:** run `WZRD_INTEL_PREFLIGHT` (free ReadinessCard). Escalate to `WZRD_INTEL_TRUST` only when you need a signed V5 receipt. Verify offline with `WZRD_VERIFY_RECEIPT`.
|
|
4
6
|
|
|
5
7
|
## Install
|
|
6
8
|
|
|
@@ -10,52 +12,122 @@ npm install @wzrd_sol/eliza-plugin
|
|
|
10
12
|
|
|
11
13
|
## Configuration
|
|
12
14
|
|
|
13
|
-
Set these in your ElizaOS runtime settings or environment:
|
|
14
|
-
|
|
15
15
|
| Variable | Required | Default | Description |
|
|
16
16
|
|----------|----------|---------|-------------|
|
|
17
|
-
| `
|
|
18
|
-
| `WZRD_API_URL` | No | `https://api.twzrd.xyz` |
|
|
19
|
-
| `
|
|
17
|
+
| `WZRD_INTEL_URL` | No | `https://intel.twzrd.xyz` | Agent Intel API (preflight, trust, verify) |
|
|
18
|
+
| `WZRD_API_URL` | No | `https://api.twzrd.xyz` | Legacy earn API (infer/report/claim) |
|
|
19
|
+
| `SOLANA_PRIVATE_KEY` | Earn lane only | — | JSON array of secret key bytes for agent Ed25519 auth |
|
|
20
|
+
|
|
21
|
+
### Wiring a paying fetch (intel paid actions)
|
|
22
|
+
|
|
23
|
+
The plugin does **not** embed a wallet. Paid `WZRD_INTEL_TRUST` needs an x402-capable `fetch` from the host:
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
import { AgentRuntime } from '@elizaos/core';
|
|
27
|
+
import wzrdPlugin, { setPayingFetch } from '@wzrd_sol/eliza-plugin';
|
|
28
|
+
import { agentcashFetch } from 'your-x402-wrapper'; // agentcash, twzrd-x402-gate, etc.
|
|
29
|
+
|
|
30
|
+
setPayingFetch(agentcashFetch);
|
|
31
|
+
|
|
32
|
+
const agent = new AgentRuntime({
|
|
33
|
+
plugins: [wzrdPlugin],
|
|
34
|
+
settings: {
|
|
35
|
+
WZRD_INTEL_URL: 'https://intel.twzrd.xyz',
|
|
36
|
+
SOLANA_PRIVATE_KEY: process.env.SOLANA_PRIVATE_KEY,
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Without a paying fetch, `WZRD_INTEL_TRUST` returns the HTTP 402 requirements and an `npx agentcash@latest fetch ...` one-liner.
|
|
20
42
|
|
|
21
43
|
## Usage
|
|
22
44
|
|
|
23
45
|
```typescript
|
|
24
|
-
import { wzrdPlugin } from
|
|
46
|
+
import { wzrdPlugin } from '@wzrd_sol/eliza-plugin';
|
|
25
47
|
|
|
26
|
-
// Register with your ElizaOS agent
|
|
27
48
|
const agent = new AgentRuntime({
|
|
28
49
|
plugins: [wzrdPlugin],
|
|
29
|
-
// ... other config
|
|
30
50
|
});
|
|
31
51
|
```
|
|
32
52
|
|
|
33
|
-
|
|
53
|
+
Programmatic SDK calls (same types as the plugin) are re-exported:
|
|
54
|
+
|
|
55
|
+
```typescript
|
|
56
|
+
import { intelPreflight, fetchIntelTrust, verifyReceipt, IntelPaymentRequiredError } from '@wzrd_sol/eliza-plugin';
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Intel actions (primary)
|
|
60
|
+
|
|
61
|
+
| Action | Auth/Pay | Description |
|
|
62
|
+
|--------|----------|-------------|
|
|
63
|
+
| `WZRD_INTEL_PREFLIGHT` | Free | ReadinessCard: decision, trust_score, can_spend, caveats, paid upsell |
|
|
64
|
+
| `WZRD_INTEL_TRUST` | x402 (~0.05 USDC) | Paid trust payload + V5 `twzrd_receipt` (needs `setPayingFetch`) |
|
|
65
|
+
| `WZRD_VERIFY_RECEIPT` | Free (offline) | Recompute leaf + Ed25519 verify; no network when pubkey is known |
|
|
66
|
+
|
|
67
|
+
### Example prompts
|
|
68
|
+
|
|
69
|
+
- "Preflight Jupiter Quote Preview before I pay 0.25 USDC to 6EF8rrect..."
|
|
70
|
+
- "Get the trust receipt for seller JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4"
|
|
71
|
+
- "Verify this receipt: {leaf, preimage, signature...}"
|
|
72
|
+
- "Is it safe to call the paid intel endpoint on this seller?"
|
|
73
|
+
|
|
74
|
+
### Free preflight (no wallet)
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
import { intelPreflightAction } from '@wzrd_sol/eliza-plugin';
|
|
78
|
+
|
|
79
|
+
// Handler reads seller_wallet / price_usdc / agent_intent from message content
|
|
80
|
+
await intelPreflightAction.handler(runtime, {
|
|
81
|
+
content: {
|
|
82
|
+
seller_wallet: 'JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4',
|
|
83
|
+
price_usdc: 0.25,
|
|
84
|
+
agent_intent: 'quote preview',
|
|
85
|
+
},
|
|
86
|
+
}, ...);
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Legacy earn actions
|
|
34
90
|
|
|
35
91
|
| Action | Auth | Description |
|
|
36
92
|
|--------|------|-------------|
|
|
37
|
-
| `
|
|
38
|
-
| `
|
|
39
|
-
| `
|
|
40
|
-
| `
|
|
41
|
-
| `
|
|
93
|
+
| `WZRD_INFER` | Agent Ed25519 | Server-witnessed inference; returns `execution_id` |
|
|
94
|
+
| `WZRD_REPORT` | Agent Ed25519 | Report outcome with `execution_id` for verified rewards |
|
|
95
|
+
| `WZRD_EARN` | Agent Ed25519 | Full infer → report → rewards check in one action |
|
|
96
|
+
| `WZRD_CLAIM` | Agent Ed25519 | Gasless CCM claim via relay |
|
|
97
|
+
| `WZRD_REWARDS` | Agent Ed25519 | Pending and lifetime CCM balance |
|
|
42
98
|
|
|
43
|
-
### Example prompts
|
|
99
|
+
### Example prompts (earn)
|
|
44
100
|
|
|
45
|
-
- "
|
|
46
|
-
- "
|
|
47
|
-
- "Check my WZRD
|
|
48
|
-
- "
|
|
49
|
-
|
|
101
|
+
- "Run inference through WZRD: explain quicksort in Python"
|
|
102
|
+
- "Earn some CCM on WZRD"
|
|
103
|
+
- "Check my WZRD rewards"
|
|
104
|
+
- "Claim my CCM"
|
|
105
|
+
|
|
106
|
+
## Test
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
cd agents/eliza-plugin
|
|
110
|
+
npm ci
|
|
111
|
+
npm run build
|
|
112
|
+
npm test
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
`npm test` loads the plugin into a real `@elizaos/core` `AgentRuntime`, runs live free preflight against `intel.twzrd.xyz`, offline receipt verify, and a mocked paid trust path.
|
|
116
|
+
|
|
117
|
+
Manual earn smoke (requires `SOLANA_PRIVATE_KEY`):
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
npx tsx test/earn-e2e.ts
|
|
121
|
+
```
|
|
50
122
|
|
|
51
123
|
## Links
|
|
52
124
|
|
|
53
|
-
- [
|
|
125
|
+
- [Agent Intel API](https://intel.twzrd.xyz)
|
|
126
|
+
- [Legacy API](https://api.twzrd.xyz)
|
|
54
127
|
- [SDK](https://www.npmjs.com/package/@wzrd_sol/sdk)
|
|
55
|
-
- [
|
|
56
|
-
- [
|
|
57
|
-
- [Agent Discovery](https://twzrd.xyz/llms.txt)
|
|
128
|
+
- [twzrd-agent-intel (Python/MCP)](https://github.com/twzrd-sol/wzrd-final/tree/main/packages/twzrd-agent-intel)
|
|
129
|
+
- [Agent discovery](https://twzrd.xyz/llms.txt)
|
|
58
130
|
|
|
59
131
|
## License
|
|
60
132
|
|
|
61
|
-
MIT
|
|
133
|
+
MIT
|
package/dist/actions/claim.d.ts
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* Agents can check current APR before deciding whether to claim or hold:
|
|
5
|
-
* WzrdClient.getMarketApr(marketId) — projected_total_apr_bps shows current yield rate.
|
|
6
|
-
* WzrdClient.getMarketPreview(marketId) — projected_multiplier_bps for live attention signal.
|
|
2
|
+
* WZRD_CLAIM — Claim accrued CCM via gasless relay.
|
|
3
|
+
* Server pays all transaction fees. Agent needs 0 SOL.
|
|
7
4
|
*/
|
|
8
5
|
import type { Action } from '@elizaos/core';
|
|
9
6
|
export declare const claimAction: Action;
|
package/dist/actions/claim.js
CHANGED
|
@@ -1,45 +1,48 @@
|
|
|
1
|
-
import { getWzrdClient } from '../client.js';
|
|
1
|
+
import { getWzrdClient } from '../client-factory.js';
|
|
2
2
|
export const claimAction = {
|
|
3
3
|
name: 'WZRD_CLAIM',
|
|
4
|
-
similes: ['WZRD_HARVEST', 'CLAIM_CCM', '
|
|
5
|
-
description: 'Claim accrued CCM tokens via gasless relay. Server pays tx fees.',
|
|
6
|
-
examples: [
|
|
4
|
+
similes: ['WZRD_HARVEST', 'CLAIM_CCM', 'COLLECT_REWARDS'],
|
|
5
|
+
description: 'Claim accrued CCM tokens via gasless relay. Server pays tx fees — agent needs 0 SOL.',
|
|
6
|
+
examples: [
|
|
7
|
+
[
|
|
7
8
|
{ name: '{{user1}}', content: { text: 'Claim my WZRD rewards' } },
|
|
8
|
-
{ name: '{{agentName}}', content: { text: 'Claimed CCM via gasless relay. Tx: 5S7L...' } },
|
|
9
|
-
]
|
|
9
|
+
{ name: '{{agentName}}', content: { text: 'Claimed 142.5 CCM via gasless relay. Tx: 5S7L...' } },
|
|
10
|
+
],
|
|
11
|
+
],
|
|
10
12
|
validate: async () => true,
|
|
11
13
|
handler: async (runtime, _msg, _state, _opt, callback) => {
|
|
12
14
|
const client = getWzrdClient(runtime);
|
|
13
|
-
let claims;
|
|
14
15
|
try {
|
|
15
|
-
|
|
16
|
+
// Check if there's anything to claim
|
|
17
|
+
const status = await client.getClaimStatus();
|
|
18
|
+
if (status.claimable <= 0) {
|
|
19
|
+
const text = `No CCM to claim right now.\n` +
|
|
20
|
+
`Cumulative: ${(status.cumulative_total / 1e9).toFixed(2)} CCM\n` +
|
|
21
|
+
`Already claimed: ${(status.claimed_total / 1e9).toFixed(2)} CCM\n` +
|
|
22
|
+
`Run WZRD_EARN first to accrue rewards.`;
|
|
23
|
+
await callback?.({ text });
|
|
24
|
+
return { success: true, data: status };
|
|
25
|
+
}
|
|
26
|
+
const result = await client.claimRelay();
|
|
27
|
+
if (result.status === 'already_claimed') {
|
|
28
|
+
await callback?.({ text: `Already claimed through root ${result.root_seq}.` });
|
|
29
|
+
return { success: true, data: result };
|
|
30
|
+
}
|
|
31
|
+
const text = `Claimed CCM via gasless relay.\n` +
|
|
32
|
+
`Amount: ${(result.cumulative_total / 1e9).toFixed(2)} CCM (cumulative)\n` +
|
|
33
|
+
`Root: ${result.root_seq}\n` +
|
|
34
|
+
`Tx: ${result.tx_sig?.slice(0, 20)}...`;
|
|
35
|
+
await callback?.({ text });
|
|
36
|
+
return { success: true, data: result };
|
|
16
37
|
}
|
|
17
38
|
catch (err) {
|
|
18
39
|
const msg = err instanceof Error ? err.message : String(err);
|
|
19
40
|
if (msg.includes('404')) {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
return { success: true, text };
|
|
41
|
+
await callback?.({ text: 'No claims found yet. Run WZRD_EARN to start accruing CCM.' });
|
|
42
|
+
return { success: true, data: {} };
|
|
23
43
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
return { success: false, error: text };
|
|
27
|
-
}
|
|
28
|
-
const claimable = claims.cumulative_total - claims.claimed_total;
|
|
29
|
-
if (claimable <= 0) {
|
|
30
|
-
const text = `No CCM to claim. Cumulative: ${claims.cumulative_total}, claimed: ${claims.claimed_total}.`;
|
|
31
|
-
await callback?.({ text });
|
|
32
|
-
return { success: true, text, data: claims };
|
|
33
|
-
}
|
|
34
|
-
const result = await client.claimRelay();
|
|
35
|
-
if (result.status === 'already_claimed') {
|
|
36
|
-
const text = `Already claimed through root ${result.root_seq}.`;
|
|
37
|
-
await callback?.({ text });
|
|
38
|
-
return { success: true, text, data: result };
|
|
44
|
+
await callback?.({ text: `Claim failed: ${msg}` });
|
|
45
|
+
return { success: false, error: msg };
|
|
39
46
|
}
|
|
40
|
-
const text = `Claimed CCM via relay. Cumulative: ${(result.cumulative_total / 1e6).toFixed(4)} CCM. ` +
|
|
41
|
-
`Root: ${result.root_seq}. Tx: ${result.tx_sig?.slice(0, 16)}...`;
|
|
42
|
-
await callback?.({ text });
|
|
43
|
-
return { success: true, text, data: result };
|
|
44
47
|
},
|
|
45
48
|
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WZRD_EARN — Full earn cycle: infer → report → check rewards.
|
|
3
|
+
*
|
|
4
|
+
* Single action that runs the complete server-witnessed earn loop.
|
|
5
|
+
* For agents that want one-shot earning without managing execution_ids.
|
|
6
|
+
*/
|
|
7
|
+
import type { Action } from '@elizaos/core';
|
|
8
|
+
export declare const earnAction: Action;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { getWzrdClient } from '../client-factory.js';
|
|
2
|
+
const EVAL_PROMPTS = {
|
|
3
|
+
code: [
|
|
4
|
+
'Write a Python function that checks if a binary tree is balanced. Include time complexity analysis.',
|
|
5
|
+
'Implement a thread-safe LRU cache in Rust with O(1) get and put operations.',
|
|
6
|
+
'Write a TypeScript generic function that deep-merges two objects, handling arrays and nested objects.',
|
|
7
|
+
],
|
|
8
|
+
chat: [
|
|
9
|
+
'Explain the difference between TCP and UDP to someone who has never programmed before.',
|
|
10
|
+
'What are the tradeoffs between microservices and monolithic architecture?',
|
|
11
|
+
'Describe how consensus works in proof-of-stake blockchains.',
|
|
12
|
+
],
|
|
13
|
+
reasoning: [
|
|
14
|
+
'A farmer has a fox, a chicken, and a bag of grain. He must cross a river in a boat that can only carry him and one item. How does he do it?',
|
|
15
|
+
'If it takes 5 machines 5 minutes to make 5 widgets, how long does it take 100 machines to make 100 widgets?',
|
|
16
|
+
'Three people check into a hotel room that costs $30. They each pay $10. The manager realizes the room should cost $25 and gives $5 to the bellboy to return. The bellboy keeps $2 and gives $1 back to each person. So each person paid $9 (total $27) plus the bellboy kept $2 (total $29). Where is the missing dollar?',
|
|
17
|
+
],
|
|
18
|
+
};
|
|
19
|
+
function pickPrompt(taskType) {
|
|
20
|
+
const prompts = EVAL_PROMPTS[taskType] || EVAL_PROMPTS.chat;
|
|
21
|
+
return prompts[Math.floor(Math.random() * prompts.length)];
|
|
22
|
+
}
|
|
23
|
+
export const earnAction = {
|
|
24
|
+
name: 'WZRD_EARN',
|
|
25
|
+
similes: ['WZRD_EARN_CCM', 'EARN_REWARDS', 'RUN_EARN_LOOP'],
|
|
26
|
+
description: 'Run the full WZRD earn cycle: pick a prompt, run server-witnessed inference, ' +
|
|
27
|
+
'report the outcome, and check pending rewards. One action, complete loop.',
|
|
28
|
+
examples: [
|
|
29
|
+
[
|
|
30
|
+
{ name: '{{user1}}', content: { text: 'Earn some CCM on WZRD' } },
|
|
31
|
+
{
|
|
32
|
+
name: '{{agentName}}',
|
|
33
|
+
content: {
|
|
34
|
+
text: 'Earn cycle complete. Model: gemini-2.5-flash, quality: 0.85, verified. Pending: 142.5 CCM.',
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
],
|
|
38
|
+
],
|
|
39
|
+
validate: async () => true,
|
|
40
|
+
handler: async (runtime, message, _state, _opt, callback) => {
|
|
41
|
+
const content = message.content;
|
|
42
|
+
const taskType = content.task_type || 'code';
|
|
43
|
+
const prompt = content.prompt || pickPrompt(taskType);
|
|
44
|
+
const client = getWzrdClient(runtime);
|
|
45
|
+
const steps = [];
|
|
46
|
+
try {
|
|
47
|
+
// Step 1: Pick model + Infer
|
|
48
|
+
steps.push('→ Picking model from leaderboard...');
|
|
49
|
+
const model = await client.pickModel(taskType);
|
|
50
|
+
steps.push(`→ Running inference: ${model} (${taskType})...`);
|
|
51
|
+
const infer = await client.infer(prompt, model, taskType);
|
|
52
|
+
steps.push(`✓ Inference: ${infer.executed_model} (${infer.provider}), quality ${infer.quality_score.toFixed(2)}, ${infer.latency_ms}ms`);
|
|
53
|
+
// Step 2: Report with execution_id
|
|
54
|
+
steps.push('→ Reporting outcome...');
|
|
55
|
+
const report = await client.report({
|
|
56
|
+
model_id: infer.requested_model,
|
|
57
|
+
execution_id: infer.execution_id,
|
|
58
|
+
task_type: taskType,
|
|
59
|
+
quality_score: infer.quality_score,
|
|
60
|
+
latency_ms: infer.latency_ms,
|
|
61
|
+
});
|
|
62
|
+
steps.push(`✓ Reported: ${report.verification_state}, contribution #${report.contribution_id}, pending ${(report.pending_ccm / 1e9).toFixed(2)} CCM`);
|
|
63
|
+
// Step 3: Check rewards
|
|
64
|
+
steps.push('→ Checking rewards...');
|
|
65
|
+
const rewards = await client.getRewards();
|
|
66
|
+
steps.push(`✓ Rewards: ${(rewards.pending_ccm / 1e9).toFixed(2)} CCM pending, ` +
|
|
67
|
+
`${(rewards.total_rewarded_ccm / 1e9).toFixed(2)} CCM lifetime` +
|
|
68
|
+
(rewards.rank ? `, rank #${rewards.rank}` : ''));
|
|
69
|
+
const text = `Earn cycle complete:\n${steps.join('\n')}`;
|
|
70
|
+
await callback?.({ text });
|
|
71
|
+
return {
|
|
72
|
+
success: true,
|
|
73
|
+
data: { infer, report, rewards },
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
catch (err) {
|
|
77
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
78
|
+
steps.push(`✗ Failed: ${msg}`);
|
|
79
|
+
await callback?.({ text: `Earn cycle failed:\n${steps.join('\n')}` });
|
|
80
|
+
return { success: false, error: msg };
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WZRD_INFER — Server-witnessed inference through WZRD.
|
|
3
|
+
*
|
|
4
|
+
* WZRD calls the AI provider (Gemini/Nous/OpenRouter), grades the response,
|
|
5
|
+
* and returns an execution_id receipt. Pass this to WZRD_REPORT for verified rewards.
|
|
6
|
+
*/
|
|
7
|
+
import type { Action } from '@elizaos/core';
|
|
8
|
+
export declare const inferAction: Action;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { getWzrdClient } from '../client-factory.js';
|
|
2
|
+
export const inferAction = {
|
|
3
|
+
name: 'WZRD_INFER',
|
|
4
|
+
similes: ['WZRD_RUN_INFERENCE', 'ASK_MODEL', 'RUN_MODEL'],
|
|
5
|
+
description: 'Run inference through WZRD. The server calls the AI provider, grades quality, ' +
|
|
6
|
+
'and returns an execution receipt. Use the execution_id with WZRD_REPORT to earn CCM.',
|
|
7
|
+
examples: [
|
|
8
|
+
[
|
|
9
|
+
{ name: '{{user1}}', content: { text: 'Run inference through WZRD: explain quicksort in Python' } },
|
|
10
|
+
{ name: '{{agentName}}', content: { text: 'Inference complete. Model: gemini-2.5-flash, quality: 0.85. execution_id: abc-123...' } },
|
|
11
|
+
],
|
|
12
|
+
],
|
|
13
|
+
validate: async () => true,
|
|
14
|
+
handler: async (runtime, message, _state, _opt, callback) => {
|
|
15
|
+
const content = message.content;
|
|
16
|
+
const prompt = content.prompt || content.text || '';
|
|
17
|
+
if (!prompt) {
|
|
18
|
+
await callback?.({ text: 'No prompt provided. Include a prompt or text to run inference.' });
|
|
19
|
+
return { success: false, error: 'No prompt' };
|
|
20
|
+
}
|
|
21
|
+
const taskType = content.task_type || 'chat';
|
|
22
|
+
const model = content.model;
|
|
23
|
+
const client = getWzrdClient(runtime);
|
|
24
|
+
try {
|
|
25
|
+
const result = await client.infer(prompt, model, taskType);
|
|
26
|
+
const text = `Inference complete.\n` +
|
|
27
|
+
`Model: ${result.executed_model} (${result.provider})\n` +
|
|
28
|
+
`Quality: ${result.quality_score.toFixed(2)}\n` +
|
|
29
|
+
`Latency: ${result.latency_ms}ms\n` +
|
|
30
|
+
`execution_id: ${result.execution_id}\n\n` +
|
|
31
|
+
`Response: ${result.response_preview}`;
|
|
32
|
+
await callback?.({ text });
|
|
33
|
+
return { success: true, data: result };
|
|
34
|
+
}
|
|
35
|
+
catch (err) {
|
|
36
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
37
|
+
await callback?.({ text: `Inference failed: ${msg}` });
|
|
38
|
+
return { success: false, error: msg };
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
};
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { intelPreflight } from '@wzrd_sol/sdk';
|
|
2
|
+
import { getIntelBase, parsePreflightInput, withTimeout } from '../intel-helpers.js';
|
|
3
|
+
function isValidBase58Wallet(s) {
|
|
4
|
+
if (!s)
|
|
5
|
+
return false;
|
|
6
|
+
return /^[1-9A-HJ-NP-Za-km-z]{32,44}$/.test(s);
|
|
7
|
+
}
|
|
8
|
+
function validatePreflight(input) {
|
|
9
|
+
if (input.seller_wallet && !isValidBase58Wallet(input.seller_wallet))
|
|
10
|
+
return 'seller_wallet must be 32-44 char base58';
|
|
11
|
+
if (input.price_usdc != null && (input.price_usdc < 0 || !Number.isFinite(input.price_usdc)))
|
|
12
|
+
return 'price_usdc must be non-negative finite number';
|
|
13
|
+
if (input.resource_name && typeof input.resource_name !== 'string')
|
|
14
|
+
return 'resource_name must be string';
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
function formatCard(card, preflightId) {
|
|
18
|
+
const lines = [
|
|
19
|
+
`ReadinessCard v${card.version}`,
|
|
20
|
+
`Decision: ${card.decision}`,
|
|
21
|
+
`Trust score: ${card.trust_score ?? 'n/a'}`,
|
|
22
|
+
`Can spend: ${card.can_spend ? 'yes' : 'no'}`,
|
|
23
|
+
];
|
|
24
|
+
if (preflightId)
|
|
25
|
+
lines.push(`Preflight ID: ${preflightId}`);
|
|
26
|
+
if (card.resource_name)
|
|
27
|
+
lines.push(`Resource: ${card.resource_name}`);
|
|
28
|
+
if (card.seller_wallet)
|
|
29
|
+
lines.push(`Seller: ${card.seller_wallet}`);
|
|
30
|
+
if (card.price_usdc != null)
|
|
31
|
+
lines.push(`Price: ${card.price_usdc} USDC`);
|
|
32
|
+
if (card.caveats?.length)
|
|
33
|
+
lines.push(`Caveats: ${card.caveats.join('; ')}`);
|
|
34
|
+
if (card.next_fixes?.length)
|
|
35
|
+
lines.push(`Next fixes: ${card.next_fixes.join('; ')}`);
|
|
36
|
+
if (card.paid_deep_dive) {
|
|
37
|
+
lines.push(`Paid deep dive available (${card.paid_price_usdc ?? 0.05} USDC) — use WZRD_INTEL_TRUST`);
|
|
38
|
+
}
|
|
39
|
+
return lines.join('\n');
|
|
40
|
+
}
|
|
41
|
+
export const intelPreflightAction = {
|
|
42
|
+
name: 'WZRD_INTEL_PREFLIGHT',
|
|
43
|
+
similes: ['WZRD_PREFLIGHT', 'INTEL_PREFLIGHT', 'READINESS_CARD'],
|
|
44
|
+
description: 'Free pre-spend ReadinessCard for a seller/resource/price/intent. Returns decision (allow/warn/block), ' +
|
|
45
|
+
'trust_score, can_spend, caveats, paid_deep_dive upsell, and root_provenance when applicable. ' +
|
|
46
|
+
'Run this before any x402 payment.',
|
|
47
|
+
examples: [
|
|
48
|
+
[
|
|
49
|
+
{
|
|
50
|
+
name: '{{user1}}',
|
|
51
|
+
content: {
|
|
52
|
+
text: 'Preflight Jupiter Quote Preview before I pay 0.25 USDC to 6EF8rrect...',
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
name: '{{agentName}}',
|
|
57
|
+
content: { text: 'ReadinessCard: decision ALLOW, trust_score 72, can_spend yes.' },
|
|
58
|
+
},
|
|
59
|
+
],
|
|
60
|
+
],
|
|
61
|
+
validate: async () => true,
|
|
62
|
+
handler: async (runtime, message, _state, _opt, callback) => {
|
|
63
|
+
const content = (message.content ?? {});
|
|
64
|
+
const input = parsePreflightInput(content);
|
|
65
|
+
if (!input.seller_wallet && !input.resource_name && !input.resource_url && !input.agent_intent) {
|
|
66
|
+
await callback?.({
|
|
67
|
+
text: 'Provide seller_wallet, resource_name, resource_url, or agent_intent for preflight. ' +
|
|
68
|
+
'Example: "Preflight seller JUP6Lkb... at 0.25 USDC"',
|
|
69
|
+
});
|
|
70
|
+
return { success: false, error: 'Missing preflight input' };
|
|
71
|
+
}
|
|
72
|
+
const vErr = validatePreflight(input);
|
|
73
|
+
if (vErr) {
|
|
74
|
+
await callback?.({ text: `Invalid preflight input: ${vErr}` });
|
|
75
|
+
return { success: false, error: vErr };
|
|
76
|
+
}
|
|
77
|
+
const apiBase = getIntelBase(runtime);
|
|
78
|
+
try {
|
|
79
|
+
const res = await withTimeout(() => intelPreflight(input, apiBase));
|
|
80
|
+
const card = res.readiness_card;
|
|
81
|
+
if (!card) {
|
|
82
|
+
const text = `Preflight OK (legacy). decision=${res.decision ?? 'unknown'}, score=${res.trust_score ?? 'n/a'}`;
|
|
83
|
+
await callback?.({ text });
|
|
84
|
+
return { success: true, data: res };
|
|
85
|
+
}
|
|
86
|
+
const preflightId = res.preflight_id;
|
|
87
|
+
const text = formatCard(card, preflightId);
|
|
88
|
+
await callback?.({ text });
|
|
89
|
+
return { success: true, data: { ...res, readiness_card: card } };
|
|
90
|
+
}
|
|
91
|
+
catch (err) {
|
|
92
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
93
|
+
await callback?.({ text: `Preflight failed: ${msg}` });
|
|
94
|
+
return { success: false, error: msg };
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WZRD_INTEL_TRUST — Paid trust payload + signed receipt (V5/V6) via x402-capable
|
|
3
|
+
* fetch. Preflight-gated: the free ReadinessCard runs BEFORE the payment and a
|
|
4
|
+
* decision=block aborts before any spend (the protocol's preflight-before-pay rule).
|
|
5
|
+
*/
|
|
6
|
+
import type { Action } from '@elizaos/core';
|
|
7
|
+
export declare const intelTrustAction: Action;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { fetchIntelTrust, preSpendGate, IntelPaymentRequiredError } from '@wzrd_sol/sdk';
|
|
2
|
+
import { extractPubkey, formatPaymentRequired, getIntelBase, withTimeout } from '../intel-helpers.js';
|
|
3
|
+
import { resolvePayingFetch } from '../paying-fetch.js';
|
|
4
|
+
export const intelTrustAction = {
|
|
5
|
+
name: 'WZRD_INTEL_TRUST',
|
|
6
|
+
similes: ['WZRD_TRUST_RECEIPT', 'INTEL_TRUST', 'GET_TRUST_RECEIPT'],
|
|
7
|
+
description: 'Paid GET /v1/intel/trust/{pubkey} (~0.05 USDC). Returns trust score + signed twzrd_receipt (V5/V6). ' +
|
|
8
|
+
'Runs the free preflight first and aborts on decision=block before spending. ' +
|
|
9
|
+
'Requires an x402-capable fetchImpl (setPayingFetch or host service). ' +
|
|
10
|
+
'Surfaces payment requirements if no payer is configured.',
|
|
11
|
+
examples: [
|
|
12
|
+
[
|
|
13
|
+
{ name: '{{user1}}', content: { text: 'Get the trust receipt for seller JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4' } },
|
|
14
|
+
{ name: '{{agentName}}', content: { text: 'Trust receipt received. score=42, receipt leaf=0x...' } },
|
|
15
|
+
],
|
|
16
|
+
],
|
|
17
|
+
validate: async () => true,
|
|
18
|
+
handler: async (runtime, message, _state, _opt, callback) => {
|
|
19
|
+
const content = (message.content ?? {});
|
|
20
|
+
const pubkey = extractPubkey(content);
|
|
21
|
+
if (!pubkey) {
|
|
22
|
+
await callback?.({ text: 'Provide a seller pubkey (32-44 char base58) for trust lookup.' });
|
|
23
|
+
return { success: false, error: 'Missing pubkey' };
|
|
24
|
+
}
|
|
25
|
+
const apiBase = getIntelBase(runtime);
|
|
26
|
+
const baseFetchImpl = resolvePayingFetch(runtime);
|
|
27
|
+
// preflight-before-pay: run the FREE ReadinessCard on the counterparty and
|
|
28
|
+
// abort on decision=block BEFORE any payment is signed/sent. failOpen=false so
|
|
29
|
+
// the block-on-block guarantee holds even if the gate errors — a reference
|
|
30
|
+
// plugin must demonstrate the safe posture, not bypass it. The preflight call
|
|
31
|
+
// is free (the gate only ever reads), so this adds no spend.
|
|
32
|
+
try {
|
|
33
|
+
const gate = await preSpendGate({ seller_wallet: pubkey }, { apiBase, failOpen: false, fetchImpl: baseFetchImpl });
|
|
34
|
+
if (!gate.allow) {
|
|
35
|
+
await callback?.({
|
|
36
|
+
text: `Preflight blocked the trust purchase for ${pubkey}.\n` +
|
|
37
|
+
`Decision: ${gate.decision}${gate.trustScore != null ? `, trust_score=${gate.trustScore}` : ''}\n` +
|
|
38
|
+
`Reason: ${gate.reason}\n` +
|
|
39
|
+
`No payment was sent.`,
|
|
40
|
+
});
|
|
41
|
+
return {
|
|
42
|
+
success: false,
|
|
43
|
+
error: 'preflight_block',
|
|
44
|
+
data: { decision: gate.decision, trustScore: gate.trustScore, reason: gate.reason },
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
catch (gateErr) {
|
|
49
|
+
// failOpen=false means a gate error should NOT silently pay. Surface it and stop.
|
|
50
|
+
const msg = gateErr instanceof Error ? gateErr.message : String(gateErr);
|
|
51
|
+
await callback?.({ text: `Preflight gate unavailable (${msg}); not spending. Try again shortly.` });
|
|
52
|
+
return { success: false, error: 'preflight_unavailable', data: { detail: msg } };
|
|
53
|
+
}
|
|
54
|
+
try {
|
|
55
|
+
const res = await withTimeout((signal) => {
|
|
56
|
+
const abortingFetch = ((input, init) => baseFetchImpl(input, { ...(init || {}), signal }));
|
|
57
|
+
return fetchIntelTrust(pubkey, { apiBase, fetchImpl: abortingFetch });
|
|
58
|
+
});
|
|
59
|
+
const receipt = res.twzrd_receipt;
|
|
60
|
+
const text = `Trust payload for ${pubkey}\n` +
|
|
61
|
+
`Score: ${res.trust?.score ?? 'n/a'}\n` +
|
|
62
|
+
`Paid: ${res.paid ? 'yes' : 'no'}\n` +
|
|
63
|
+
(res.tx ? `Settlement tx: ${res.tx}\n` : '') +
|
|
64
|
+
(receipt
|
|
65
|
+
? `Receipt v${receipt.version}, leaf: ${receipt.leaf}\n` +
|
|
66
|
+
`Use WZRD_VERIFY_RECEIPT to verify offline.`
|
|
67
|
+
: 'No twzrd_receipt in response.');
|
|
68
|
+
await callback?.({ text });
|
|
69
|
+
return { success: true, data: res };
|
|
70
|
+
}
|
|
71
|
+
catch (err) {
|
|
72
|
+
if (err instanceof IntelPaymentRequiredError) {
|
|
73
|
+
const text = formatPaymentRequired(err, apiBase, pubkey);
|
|
74
|
+
await callback?.({ text });
|
|
75
|
+
return { success: false, error: 'payment_required', data: { paymentRequirements: err.paymentRequirements } };
|
|
76
|
+
}
|
|
77
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
78
|
+
await callback?.({ text: `Intel trust failed: ${msg}` });
|
|
79
|
+
return { success: false, error: msg };
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WZRD_REPORT — Report a model pick with execution receipt for verified CCM rewards.
|
|
3
|
+
*
|
|
4
|
+
* Must be called after WZRD_INFER. Pass the execution_id from the infer result
|
|
5
|
+
* to get server-verified status and quality-weighted rewards.
|
|
6
|
+
*/
|
|
7
|
+
import type { Action } from '@elizaos/core';
|
|
8
|
+
export declare const reportAction: Action;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { getWzrdClient } from '../client-factory.js';
|
|
2
|
+
export const reportAction = {
|
|
3
|
+
name: 'WZRD_REPORT',
|
|
4
|
+
similes: ['WZRD_REPORT_OUTCOME', 'REPORT_MODEL_PICK', 'SUBMIT_SIGNAL'],
|
|
5
|
+
description: 'Report a model pick to WZRD with an execution_id from WZRD_INFER. ' +
|
|
6
|
+
'Verified reports earn CCM rewards with quality multiplier.',
|
|
7
|
+
examples: [
|
|
8
|
+
[
|
|
9
|
+
{ name: '{{user1}}', content: { text: 'Report the inference result to earn CCM' } },
|
|
10
|
+
{ name: '{{agentName}}', content: { text: 'Reported. Verification: verified, contribution #4521.' } },
|
|
11
|
+
],
|
|
12
|
+
],
|
|
13
|
+
validate: async () => true,
|
|
14
|
+
handler: async (runtime, message, _state, _opt, callback) => {
|
|
15
|
+
const content = message.content;
|
|
16
|
+
if (!content.execution_id || !content.model_id) {
|
|
17
|
+
await callback?.({
|
|
18
|
+
text: 'Missing required: execution_id and model_id. Run WZRD_INFER first to get an execution receipt.',
|
|
19
|
+
});
|
|
20
|
+
return { success: false, error: 'Missing execution_id or model_id' };
|
|
21
|
+
}
|
|
22
|
+
const client = getWzrdClient(runtime);
|
|
23
|
+
try {
|
|
24
|
+
const result = await client.report({
|
|
25
|
+
model_id: content.model_id,
|
|
26
|
+
execution_id: content.execution_id,
|
|
27
|
+
task_type: content.task_type,
|
|
28
|
+
quality_score: content.quality_score,
|
|
29
|
+
latency_ms: content.latency_ms,
|
|
30
|
+
});
|
|
31
|
+
const text = `Reported to WZRD.\n` +
|
|
32
|
+
`Verification: ${result.verification_state}\n` +
|
|
33
|
+
`Contribution: #${result.contribution_id}\n` +
|
|
34
|
+
`Pending CCM: ${(result.pending_ccm / 1e9).toFixed(2)}\n` +
|
|
35
|
+
`Pipeline: ${result.pipeline_state}`;
|
|
36
|
+
await callback?.({ text });
|
|
37
|
+
return { success: true, data: result };
|
|
38
|
+
}
|
|
39
|
+
catch (err) {
|
|
40
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
41
|
+
await callback?.({ text: `Report failed: ${msg}` });
|
|
42
|
+
return { success: false, error: msg };
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
};
|