@agent-pulse/openclaw-skill 1.0.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 +50 -0
- package/SKILL.md +148 -0
- package/dist/gate-schema.json +75 -0
- package/dist/index.d.ts +102 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +408 -0
- package/dist/index.js.map +1 -0
- package/dist/package-lock.json +325 -0
- package/dist/package.json +53 -0
- package/dist/tsconfig.json +31 -0
- package/dist/types.d.ts +147 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/gate-schema.json +75 -0
- package/package.json +53 -0
package/README.md
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# @agent-pulse/openclaw-skill
|
|
2
|
+
|
|
3
|
+
OpenClaw skill integration for [AgentPulse SDK](https://www.npmjs.com/package/@agent-pulse/sdk) gating. Provides liveness-based gate checks for incoming and outgoing agent requests.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @agent-pulse/openclaw-skill @agent-pulse/sdk
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import { startup, withGate, getGateStatus } from "@agent-pulse/openclaw-skill";
|
|
15
|
+
|
|
16
|
+
// Initialize gate from skill YAML config
|
|
17
|
+
const result = await startup({
|
|
18
|
+
enabled: true,
|
|
19
|
+
mode: "strict", // "strict" | "warn" | "log"
|
|
20
|
+
threshold: "24h", // liveness threshold
|
|
21
|
+
chainId: 84532, // Base Sepolia (default)
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
if (result.success && result.gate) {
|
|
25
|
+
// Gate an incoming request
|
|
26
|
+
const allowed = await result.gate.gateIncoming("0x...");
|
|
27
|
+
|
|
28
|
+
// Or use the middleware wrapper
|
|
29
|
+
const protectedAction = withGate(async (ctx, input) => {
|
|
30
|
+
// your action logic
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Gate Modes
|
|
36
|
+
|
|
37
|
+
| Mode | On Reject | On Error |
|
|
38
|
+
|----------|---------------------|---------------------|
|
|
39
|
+
| `strict` | Throws error (403) | Throws error (500) |
|
|
40
|
+
| `warn` | Logs warning | Logs, allows |
|
|
41
|
+
| `log` | Telemetry only | Silent, allows |
|
|
42
|
+
|
|
43
|
+
## Links
|
|
44
|
+
|
|
45
|
+
- [AgentPulse SDK](https://www.npmjs.com/package/@agent-pulse/sdk)
|
|
46
|
+
- [Repository](https://github.com/consensus-hq/agent-pulse)
|
|
47
|
+
|
|
48
|
+
## License
|
|
49
|
+
|
|
50
|
+
MIT
|
package/SKILL.md
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
# OpenClaw Skill - AgentPulse Gate Integration
|
|
2
|
+
|
|
3
|
+
This OpenClaw skill integrates the AgentPulse SDK for bidirectional gating of agent interactions. It provides liveness verification before allowing skill actions to proceed.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The AgentPulse Gate skill enables OpenClaw agents to:
|
|
8
|
+
|
|
9
|
+
1. **Verify agent liveness** before processing incoming requests
|
|
10
|
+
2. **Check target agent status** before making outgoing calls
|
|
11
|
+
3. **Enforce gating policies** based on configurable modes
|
|
12
|
+
4. **Surface gate status** in orchestrator queries
|
|
13
|
+
|
|
14
|
+
## Configuration
|
|
15
|
+
|
|
16
|
+
Add a `gate` block to your skill YAML configuration:
|
|
17
|
+
|
|
18
|
+
```yaml
|
|
19
|
+
gate:
|
|
20
|
+
enabled: true
|
|
21
|
+
mode: strict # strict | warn | log
|
|
22
|
+
threshold: 24h # duration string (e.g., 30m, 1h, 24h, 7d)
|
|
23
|
+
chainId: 84532 # optional: Base Sepolia (default) or 8453 for Base Mainnet
|
|
24
|
+
rpcUrl: https://... # optional: custom RPC endpoint
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### Gate Modes
|
|
28
|
+
|
|
29
|
+
| Mode | Behavior |
|
|
30
|
+
|------|----------|
|
|
31
|
+
| `strict` | Reject requests from/to dead agents with hard error |
|
|
32
|
+
| `warn` | Allow all requests, log warnings for dead agents |
|
|
33
|
+
| `log` | Passive telemetry only, no enforcement |
|
|
34
|
+
|
|
35
|
+
### Threshold Format
|
|
36
|
+
|
|
37
|
+
The `threshold` field accepts duration strings:
|
|
38
|
+
- `30m` - 30 minutes
|
|
39
|
+
- `1h` - 1 hour
|
|
40
|
+
- `24h` - 24 hours
|
|
41
|
+
- `1d` - 1 day
|
|
42
|
+
- `7d` - 7 days
|
|
43
|
+
|
|
44
|
+
## Skill Startup Hook
|
|
45
|
+
|
|
46
|
+
The skill automatically initializes the AgentPulse SDK on startup:
|
|
47
|
+
|
|
48
|
+
1. Reads gate configuration from skill YAML
|
|
49
|
+
2. Validates configuration against `gate-schema.json`
|
|
50
|
+
3. Initializes AgentPulseClient with provided settings
|
|
51
|
+
4. Creates AgentPulseGate instance with configured mode
|
|
52
|
+
5. **Gate failure is surfaced** - if RPC is unreachable, skill errors per mode
|
|
53
|
+
|
|
54
|
+
### Mode Mapping
|
|
55
|
+
|
|
56
|
+
| Mode | Gate Configuration |
|
|
57
|
+
|------|-------------------|
|
|
58
|
+
| `strict` | `gateIncoming` + `gateOutgoing` with hard reject |
|
|
59
|
+
| `warn` | Gates enabled, warnings logged, requests proceed |
|
|
60
|
+
| `log` | Passive telemetry, all requests proceed |
|
|
61
|
+
|
|
62
|
+
## Gate Activation Order
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
1. Skill Startup
|
|
66
|
+
└── Initialize AgentPulse SDK
|
|
67
|
+
└── Fail loudly if RPC unreachable (strict/warn)
|
|
68
|
+
|
|
69
|
+
2. Incoming Request
|
|
70
|
+
└── gateIncoming(requesterAddr)
|
|
71
|
+
├── strict: reject if dead → throw error
|
|
72
|
+
├── warn: log warning if dead → proceed
|
|
73
|
+
└── log: log status → proceed
|
|
74
|
+
|
|
75
|
+
3. Execute Skill Action/Evaluator
|
|
76
|
+
|
|
77
|
+
4. Outgoing Request (if applicable)
|
|
78
|
+
└── gateOutgoing(targetAddr)
|
|
79
|
+
└── Same behavior as incoming
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Status Output
|
|
83
|
+
|
|
84
|
+
The skill adds a `gate` section to skill status for orchestrator queries:
|
|
85
|
+
|
|
86
|
+
```json
|
|
87
|
+
{
|
|
88
|
+
"gate": {
|
|
89
|
+
"enabled": true,
|
|
90
|
+
"mode": "strict",
|
|
91
|
+
"threshold": "24h",
|
|
92
|
+
"status": "active",
|
|
93
|
+
"lastCheck": 1707254400,
|
|
94
|
+
"agentsChecked": 42,
|
|
95
|
+
"agentsRejected": 3
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## API
|
|
101
|
+
|
|
102
|
+
### `gateIncoming(requesterAddr: Address): Promise<boolean>`
|
|
103
|
+
|
|
104
|
+
Check if an incoming request from `requesterAddr` should be allowed.
|
|
105
|
+
|
|
106
|
+
- Returns `true` if allowed
|
|
107
|
+
- Throws `AgentPulseError` in strict mode if agent is dead
|
|
108
|
+
- Logs and returns `true` in warn/log modes
|
|
109
|
+
|
|
110
|
+
### `gateOutgoing(targetAddr: Address): Promise<boolean>`
|
|
111
|
+
|
|
112
|
+
Check if an outgoing request to `targetAddr` should be allowed.
|
|
113
|
+
|
|
114
|
+
- Same behavior as `gateIncoming`
|
|
115
|
+
|
|
116
|
+
### `getGateStatus(): GateStatus`
|
|
117
|
+
|
|
118
|
+
Get current gate status for monitoring.
|
|
119
|
+
|
|
120
|
+
## CLI Commands
|
|
121
|
+
|
|
122
|
+
The skill provides shell scripts for CLI interaction with the AgentPulse protocol:
|
|
123
|
+
|
|
124
|
+
| Command | Usage | Description |
|
|
125
|
+
|---------|-------|-------------|
|
|
126
|
+
| `attest.sh` | `./attest.sh <addr> <outcome> [--task-id <id>]` | Submit a peer attestation |
|
|
127
|
+
| `reputation.sh` | `./reputation.sh <addr> [--format json]` | Show composite reputation score and stats |
|
|
128
|
+
| `check.sh` | `./check.sh <addr> --min-score <n>` | Verify if an agent meets a reputation threshold |
|
|
129
|
+
| `attestations.sh` | `./attestations.sh <addr> --received\|--given` | List historical attestations |
|
|
130
|
+
|
|
131
|
+
Note: In the final distribution, these are aliased to `agent-pulse <command>`.
|
|
132
|
+
|
|
133
|
+
## Error Handling
|
|
134
|
+
|
|
135
|
+
If the AgentPulse SDK fails to initialize (bad RPC, network issues):
|
|
136
|
+
|
|
137
|
+
- **strict mode**: Skill startup fails with error
|
|
138
|
+
- **warn mode**: Warning logged, skill continues without gating
|
|
139
|
+
- **log mode**: Silent failure, passive mode disabled
|
|
140
|
+
|
|
141
|
+
## Integration Example
|
|
142
|
+
|
|
143
|
+
See `example-gated-skill.yaml` for complete configuration examples.
|
|
144
|
+
|
|
145
|
+
## Dependencies
|
|
146
|
+
|
|
147
|
+
- `@agent-pulse/sdk` - AgentPulse protocol SDK
|
|
148
|
+
- `viem` - Ethereum interactions
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"$id": "https://agent-pulse.io/schemas/openclaw-gate.json",
|
|
4
|
+
"title": "OpenClaw AgentPulse Gate Configuration",
|
|
5
|
+
"description": "Schema for the gate block in OpenClaw skill YAML configurations",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"properties": {
|
|
8
|
+
"enabled": {
|
|
9
|
+
"type": "boolean",
|
|
10
|
+
"description": "Whether gating is enabled for this skill",
|
|
11
|
+
"default": false
|
|
12
|
+
},
|
|
13
|
+
"mode": {
|
|
14
|
+
"type": "string",
|
|
15
|
+
"enum": ["strict", "warn", "log"],
|
|
16
|
+
"description": "Gating mode: strict (reject dead agents), warn (allow with warning), log (passive telemetry only)",
|
|
17
|
+
"default": "strict"
|
|
18
|
+
},
|
|
19
|
+
"threshold": {
|
|
20
|
+
"type": "string",
|
|
21
|
+
"description": "Duration string specifying the maximum time since last pulse (e.g., '24h', '1d', '30m')",
|
|
22
|
+
"pattern": "^[0-9]+[smhdw]$",
|
|
23
|
+
"examples": ["24h", "1d", "30m", "7d"]
|
|
24
|
+
},
|
|
25
|
+
"rpcUrl": {
|
|
26
|
+
"type": "string",
|
|
27
|
+
"format": "uri",
|
|
28
|
+
"description": "Optional RPC URL for AgentPulse SDK connection. Uses default if not specified."
|
|
29
|
+
},
|
|
30
|
+
"chainId": {
|
|
31
|
+
"type": "integer",
|
|
32
|
+
"description": "Chain ID for the AgentPulse protocol (default: 84532 for Base Sepolia)",
|
|
33
|
+
"default": 84532
|
|
34
|
+
},
|
|
35
|
+
"contracts": {
|
|
36
|
+
"type": "object",
|
|
37
|
+
"description": "Optional contract address overrides",
|
|
38
|
+
"properties": {
|
|
39
|
+
"pulseToken": {
|
|
40
|
+
"type": "string",
|
|
41
|
+
"pattern": "^0x[a-fA-F0-9]{40}$",
|
|
42
|
+
"description": "PULSE token contract address"
|
|
43
|
+
},
|
|
44
|
+
"pulseRegistry": {
|
|
45
|
+
"type": "string",
|
|
46
|
+
"pattern": "^0x[a-fA-F0-9]{40}$",
|
|
47
|
+
"description": "PulseRegistry contract address"
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
"required": ["enabled"],
|
|
53
|
+
"if": {
|
|
54
|
+
"properties": {
|
|
55
|
+
"enabled": { "const": true }
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
"then": {
|
|
59
|
+
"required": ["mode", "threshold"]
|
|
60
|
+
},
|
|
61
|
+
"additionalProperties": false,
|
|
62
|
+
"examples": [
|
|
63
|
+
{
|
|
64
|
+
"enabled": true,
|
|
65
|
+
"mode": "strict",
|
|
66
|
+
"threshold": "24h"
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
"enabled": true,
|
|
70
|
+
"mode": "warn",
|
|
71
|
+
"threshold": "12h",
|
|
72
|
+
"chainId": 8453
|
|
73
|
+
}
|
|
74
|
+
]
|
|
75
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenClaw Skill - AgentPulse Gate Integration
|
|
3
|
+
*
|
|
4
|
+
* Main implementation of the OpenClaw skill framework integration.
|
|
5
|
+
* Provides startup hook, gate activation, and status reporting.
|
|
6
|
+
*
|
|
7
|
+
* @module openclaw-skill
|
|
8
|
+
*/
|
|
9
|
+
import { type Address } from "viem";
|
|
10
|
+
import { AgentPulseGate } from "@agent-pulse/sdk";
|
|
11
|
+
import type { GateConfig, ParsedThreshold, GateRuntimeStatus, GateStats, GateStatusOutput, OpenClawGate as IOpenClawGate, SkillStartupResult } from "./types.js";
|
|
12
|
+
/**
|
|
13
|
+
* Validate gate configuration against JSON Schema
|
|
14
|
+
*/
|
|
15
|
+
export declare function validateGateConfig(config: unknown): config is GateConfig;
|
|
16
|
+
/**
|
|
17
|
+
* Parse duration string to seconds
|
|
18
|
+
* @param threshold - Duration string (e.g., "24h", "30m")
|
|
19
|
+
* @returns Parsed threshold or null if invalid
|
|
20
|
+
*/
|
|
21
|
+
export declare function parseThreshold(threshold: string): ParsedThreshold | null;
|
|
22
|
+
/**
|
|
23
|
+
* OpenClaw Gate implementation wrapping AgentPulse SDK
|
|
24
|
+
*/
|
|
25
|
+
declare class OpenClawGate implements IOpenClawGate {
|
|
26
|
+
private gate;
|
|
27
|
+
private config;
|
|
28
|
+
private _status;
|
|
29
|
+
private _stats;
|
|
30
|
+
constructor(gate: AgentPulseGate, config: GateConfig);
|
|
31
|
+
/**
|
|
32
|
+
* Gate an incoming request
|
|
33
|
+
* @param requesterAddr - Address of the requesting agent
|
|
34
|
+
* @returns true if allowed, throws in strict mode if rejected
|
|
35
|
+
*/
|
|
36
|
+
gateIncoming(requesterAddr: Address): Promise<boolean>;
|
|
37
|
+
/**
|
|
38
|
+
* Gate an outgoing request
|
|
39
|
+
* @param targetAddr - Address of the target agent
|
|
40
|
+
* @returns true if allowed, throws in strict mode if rejected
|
|
41
|
+
*/
|
|
42
|
+
gateOutgoing(targetAddr: Address): Promise<boolean>;
|
|
43
|
+
/**
|
|
44
|
+
* Internal check implementation
|
|
45
|
+
*/
|
|
46
|
+
private performCheck;
|
|
47
|
+
/**
|
|
48
|
+
* Get current gate status
|
|
49
|
+
*/
|
|
50
|
+
getStatus(): GateRuntimeStatus;
|
|
51
|
+
/**
|
|
52
|
+
* Get gate statistics
|
|
53
|
+
*/
|
|
54
|
+
getStats(): GateStats;
|
|
55
|
+
/**
|
|
56
|
+
* Get full status output for orchestrator queries
|
|
57
|
+
*/
|
|
58
|
+
getStatusOutput(): GateStatusOutput;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Skill startup hook - initializes AgentPulse SDK
|
|
62
|
+
*
|
|
63
|
+
* This MUST be called before any skill action/evaluator runs.
|
|
64
|
+
* Gate initialization failure is surfaced based on mode:
|
|
65
|
+
* - strict: Throws error, skill startup fails
|
|
66
|
+
* - warn: Logs warning, continues without gating
|
|
67
|
+
* - log: Silent, continues without gating
|
|
68
|
+
*
|
|
69
|
+
* @param config - Gate configuration from skill YAML
|
|
70
|
+
* @returns Skill startup result with gate instance
|
|
71
|
+
*/
|
|
72
|
+
export declare function startup(config: unknown): Promise<SkillStartupResult>;
|
|
73
|
+
/**
|
|
74
|
+
* Middleware that activates gate BEFORE any skill action/evaluator
|
|
75
|
+
*
|
|
76
|
+
* Usage in skill definition:
|
|
77
|
+
* ```typescript
|
|
78
|
+
* actions: {
|
|
79
|
+
* myAction: withGate((ctx, input) => { ... })
|
|
80
|
+
* }
|
|
81
|
+
* ```
|
|
82
|
+
*/
|
|
83
|
+
export declare function withGate<TInput, TOutput>(action: (ctx: {
|
|
84
|
+
gate?: IOpenClawGate;
|
|
85
|
+
}, input: TInput) => Promise<TOutput>, options?: {
|
|
86
|
+
direction?: "incoming" | "outgoing";
|
|
87
|
+
address?: Address;
|
|
88
|
+
}): (ctx: {
|
|
89
|
+
gate?: IOpenClawGate;
|
|
90
|
+
}, input: TInput & {
|
|
91
|
+
from?: Address;
|
|
92
|
+
to?: Address;
|
|
93
|
+
}) => Promise<TOutput>;
|
|
94
|
+
/**
|
|
95
|
+
* Get gate status for orchestrator queries
|
|
96
|
+
* @param gate - Gate instance (if initialized)
|
|
97
|
+
* @returns Gate status output
|
|
98
|
+
*/
|
|
99
|
+
export declare function getGateStatus(gate?: IOpenClawGate): GateStatusOutput | null;
|
|
100
|
+
export { OpenClawGate };
|
|
101
|
+
export type { GateConfig, GateStatusOutput, SkillStartupResult };
|
|
102
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,KAAK,OAAO,EAAa,MAAM,MAAM,CAAC;AAC/C,OAAO,EAEL,cAAc,EAIf,MAAM,kBAAkB,CAAC;AAG1B,OAAO,KAAK,EACV,UAAU,EACV,eAAe,EACf,iBAAiB,EACjB,SAAS,EACT,gBAAgB,EAChB,YAAY,IAAI,aAAa,EAC7B,kBAAkB,EACnB,MAAM,YAAY,CAAC;AAwBpB;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,IAAI,UAAU,CAIxE;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CAaxE;AAMD;;GAEG;AACH,cAAM,YAAa,YAAW,aAAa;IACzC,OAAO,CAAC,IAAI,CAAiB;IAC7B,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,OAAO,CAAoB;IACnC,OAAO,CAAC,MAAM,CAAY;gBAEd,IAAI,EAAE,cAAc,EAAE,MAAM,EAAE,UAAU;IAsBpD;;;;OAIG;IACG,YAAY,CAAC,aAAa,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAI5D;;;;OAIG;IACG,YAAY,CAAC,UAAU,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAIzD;;OAEG;YACW,YAAY;IA+D1B;;OAEG;IACH,SAAS,IAAI,iBAAiB;IAI9B;;OAEG;IACH,QAAQ,IAAI,SAAS;IAIrB;;OAEG;IACH,eAAe,IAAI,gBAAgB;CAepC;AAMD;;;;;;;;;;;GAWG;AACH,wBAAsB,OAAO,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAsK1E;AAMD;;;;;;;;;GASG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,OAAO,EACtC,MAAM,EAAE,CAAC,GAAG,EAAE;IAAE,IAAI,CAAC,EAAE,aAAa,CAAA;CAAE,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,EAC1E,OAAO,CAAC,EAAE;IAAE,SAAS,CAAC,EAAE,UAAU,GAAG,UAAU,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,IAEtD,KAAK;IAAE,IAAI,CAAC,EAAE,aAAa,CAAA;CAAE,EAAE,OAAO,MAAM,GAAG;IAAE,IAAI,CAAC,EAAE,OAAO,CAAC;IAAC,EAAE,CAAC,EAAE,OAAO,CAAA;CAAE,KAAG,OAAO,CAAC,OAAO,CAAC,CAgBjH;AAMD;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,CAAC,EAAE,aAAa,GAAG,gBAAgB,GAAG,IAAI,CA2B3E;AAMD,OAAO,EAAE,YAAY,EAAE,CAAC;AACxB,YAAY,EAAE,UAAU,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,CAAC"}
|