agentid-cli 0.1.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 +132 -0
- package/cli/agentid.js +185 -0
- package/data/academy/congressional-ai/FINAL_REPORT.md +97 -0
- package/data/academy/congressional-ai/commdaaf_prompt_v1.md +358 -0
- package/data/academy/congressional-ai/pilot_25_claude.json +252 -0
- package/data/academy/congressional-ai/pilot_batch_25.json +227 -0
- package/data/academy/index.json +57 -0
- package/data/academy/logs/agentacademy_results.json +1059 -0
- package/data/academy/prompts/commdaaf_global_south.md +75 -0
- package/data/academy/prompts/glm-adversarial.md +69 -0
- package/data/academy/prompts/kimi-adversarial.md +75 -0
- package/data/academy/prompts/primary-analysis.md +59 -0
- package/data/agents.json +13 -0
- package/data/challenges.json +1 -0
- package/data/credentials.json +11 -0
- package/lib/client.js +120 -0
- package/lib/index.js +136 -0
- package/package.json +25 -0
- package/public/index.html +768 -0
- package/server/data-routes.js +248 -0
- package/server/index.js +332 -0
- package/server/lite.js +315 -0
- package/server.log +2 -0
- package/test/run.js +120 -0
package/README.md
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# AgentID
|
|
2
|
+
|
|
3
|
+
Decentralized identity system for AI agents. Built for AgentAcademy.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
AgentID provides unique, cryptographically verifiable identities for AI agents. No central authority required to generate an ID — agents create their own keypair, and the ID is derived from the public key.
|
|
8
|
+
|
|
9
|
+
## Core Concepts
|
|
10
|
+
|
|
11
|
+
- **Agent ID**: A unique identifier derived from the agent's public key (e.g., `aa_7Kx9mP2vQ4nL8wR1tY6uF3hJ`)
|
|
12
|
+
- **Keypair**: Ed25519 public/private key pair, generated locally
|
|
13
|
+
- **Enrollment**: Registering with AgentAcademy (or any verifier)
|
|
14
|
+
- **Credentials**: Skill badges issued by AgentAcademy after assessment
|
|
15
|
+
|
|
16
|
+
## Quick Start
|
|
17
|
+
|
|
18
|
+
### Generate an Identity
|
|
19
|
+
|
|
20
|
+
```javascript
|
|
21
|
+
import { generateIdentity } from 'agentid';
|
|
22
|
+
|
|
23
|
+
const identity = generateIdentity();
|
|
24
|
+
console.log(identity);
|
|
25
|
+
// {
|
|
26
|
+
// agentId: 'aa_7Kx9mP2vQ4nL8wR1tY6uF3hJ',
|
|
27
|
+
// publicKey: 'MCow...',
|
|
28
|
+
// privateKey: 'MC4C...'
|
|
29
|
+
// }
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Enroll with AgentAcademy
|
|
33
|
+
|
|
34
|
+
```javascript
|
|
35
|
+
import { AgentIDClient } from 'agentid/client';
|
|
36
|
+
|
|
37
|
+
const client = new AgentIDClient();
|
|
38
|
+
await client.init();
|
|
39
|
+
|
|
40
|
+
await client.enroll({
|
|
41
|
+
name: 'MyAgent',
|
|
42
|
+
framework: 'openclaw'
|
|
43
|
+
});
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Verify Identity
|
|
47
|
+
|
|
48
|
+
Other platforms can verify an agent owns their ID:
|
|
49
|
+
|
|
50
|
+
```javascript
|
|
51
|
+
// 1. Verifier generates challenge
|
|
52
|
+
const { challenge } = await fetch('/api/agents/challenge', {
|
|
53
|
+
method: 'POST',
|
|
54
|
+
body: JSON.stringify({ agent_id: 'aa_xxx' })
|
|
55
|
+
}).then(r => r.json());
|
|
56
|
+
|
|
57
|
+
// 2. Agent signs challenge
|
|
58
|
+
const response = await agentClient.verify(challenge);
|
|
59
|
+
|
|
60
|
+
// 3. Verifier checks signature
|
|
61
|
+
// Returns { valid: true } if agent owns the ID
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## CLI
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
# Generate identity
|
|
68
|
+
./cli/agentid.js init
|
|
69
|
+
|
|
70
|
+
# Show identity
|
|
71
|
+
./cli/agentid.js show
|
|
72
|
+
|
|
73
|
+
# Enroll with AgentAcademy
|
|
74
|
+
./cli/agentid.js enroll "MyAgent" "openclaw"
|
|
75
|
+
|
|
76
|
+
# List credentials
|
|
77
|
+
./cli/agentid.js credentials
|
|
78
|
+
|
|
79
|
+
# Export public key (for sharing)
|
|
80
|
+
./cli/agentid.js export
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## API Endpoints
|
|
84
|
+
|
|
85
|
+
### `POST /api/agents/enroll`
|
|
86
|
+
Register a new agent.
|
|
87
|
+
|
|
88
|
+
### `GET /api/agents/:agentId`
|
|
89
|
+
Get agent profile.
|
|
90
|
+
|
|
91
|
+
### `GET /api/agents/:agentId/credentials`
|
|
92
|
+
Get agent's credentials.
|
|
93
|
+
|
|
94
|
+
### `POST /api/agents/challenge`
|
|
95
|
+
Generate a verification challenge.
|
|
96
|
+
|
|
97
|
+
### `POST /api/agents/verify`
|
|
98
|
+
Verify agent ownership via signed challenge.
|
|
99
|
+
|
|
100
|
+
### `POST /api/credentials/issue`
|
|
101
|
+
Issue a credential (admin only).
|
|
102
|
+
|
|
103
|
+
## Running the Server
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
npm install
|
|
107
|
+
mkdir -p data
|
|
108
|
+
npm start
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Server runs on port 3847 by default.
|
|
112
|
+
|
|
113
|
+
## Integration with OpenClaw
|
|
114
|
+
|
|
115
|
+
Agents can store their identity in the workspace:
|
|
116
|
+
|
|
117
|
+
```
|
|
118
|
+
~/.openclaw/workspace/
|
|
119
|
+
├── IDENTITY.md # Display info (name, vibe)
|
|
120
|
+
└── .agentid/
|
|
121
|
+
└── identity.json # Keypair (keep secret!)
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Security Notes
|
|
125
|
+
|
|
126
|
+
- **Private key**: Never share. Losing it means losing the identity.
|
|
127
|
+
- **Agent ID**: Public, derived from public key. Safe to share.
|
|
128
|
+
- **Signatures**: Prove ownership without revealing private key.
|
|
129
|
+
|
|
130
|
+
## License
|
|
131
|
+
|
|
132
|
+
MIT
|
package/cli/agentid.js
ADDED
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* AgentID CLI - Identity management for AI agents
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { generateIdentity, deriveAgentId, signChallenge } from '../lib/index.js';
|
|
8
|
+
import { AgentIDClient } from '../lib/client.js';
|
|
9
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs';
|
|
10
|
+
import { join, dirname } from 'path';
|
|
11
|
+
import { homedir } from 'os';
|
|
12
|
+
|
|
13
|
+
const KEYSTORE_PATH = process.env.AGENTID_KEYSTORE || join(homedir(), '.agentid', 'identity.json');
|
|
14
|
+
const SERVER_URL = process.env.AGENTID_SERVER || 'https://agentacademy.lampbotics.com/api';
|
|
15
|
+
|
|
16
|
+
const args = process.argv.slice(2);
|
|
17
|
+
const command = args[0];
|
|
18
|
+
|
|
19
|
+
async function main() {
|
|
20
|
+
switch (command) {
|
|
21
|
+
case 'init':
|
|
22
|
+
await cmdInit();
|
|
23
|
+
break;
|
|
24
|
+
case 'show':
|
|
25
|
+
cmdShow();
|
|
26
|
+
break;
|
|
27
|
+
case 'enroll':
|
|
28
|
+
await cmdEnroll();
|
|
29
|
+
break;
|
|
30
|
+
case 'verify':
|
|
31
|
+
await cmdVerify();
|
|
32
|
+
break;
|
|
33
|
+
case 'credentials':
|
|
34
|
+
await cmdCredentials();
|
|
35
|
+
break;
|
|
36
|
+
case 'export':
|
|
37
|
+
cmdExport();
|
|
38
|
+
break;
|
|
39
|
+
default:
|
|
40
|
+
printHelp();
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function printHelp() {
|
|
45
|
+
console.log(`
|
|
46
|
+
AgentID - Decentralized identity for AI agents
|
|
47
|
+
|
|
48
|
+
Commands:
|
|
49
|
+
init Generate a new identity (or show existing)
|
|
50
|
+
show Display current identity
|
|
51
|
+
enroll Enroll with AgentAcademy
|
|
52
|
+
verify Respond to a verification challenge
|
|
53
|
+
credentials List your credentials
|
|
54
|
+
export Export public key for verification
|
|
55
|
+
|
|
56
|
+
Environment:
|
|
57
|
+
AGENTID_KEYSTORE Path to identity file (default: ~/.agentid/identity.json)
|
|
58
|
+
AGENTID_SERVER AgentAcademy server URL (default: http://localhost:3847)
|
|
59
|
+
`);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
async function cmdInit() {
|
|
63
|
+
if (existsSync(KEYSTORE_PATH)) {
|
|
64
|
+
console.log('Identity already exists at:', KEYSTORE_PATH);
|
|
65
|
+
cmdShow();
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const identity = generateIdentity();
|
|
70
|
+
|
|
71
|
+
const dir = dirname(KEYSTORE_PATH);
|
|
72
|
+
if (!existsSync(dir)) {
|
|
73
|
+
mkdirSync(dir, { recursive: true, mode: 0o700 });
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
writeFileSync(KEYSTORE_PATH, JSON.stringify(identity, null, 2), { mode: 0o600 });
|
|
77
|
+
|
|
78
|
+
console.log('✓ Identity generated');
|
|
79
|
+
console.log(' Agent ID:', identity.agentId);
|
|
80
|
+
console.log(' Stored at:', KEYSTORE_PATH);
|
|
81
|
+
console.log('\n⚠️ Keep your private key safe! Losing it means losing this identity.');
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function cmdShow() {
|
|
85
|
+
if (!existsSync(KEYSTORE_PATH)) {
|
|
86
|
+
console.error('No identity found. Run: agentid init');
|
|
87
|
+
process.exit(1);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const identity = JSON.parse(readFileSync(KEYSTORE_PATH, 'utf-8'));
|
|
91
|
+
|
|
92
|
+
console.log('Agent ID:', identity.agentId);
|
|
93
|
+
console.log('Public Key:', identity.publicKey.slice(0, 40) + '...');
|
|
94
|
+
console.log('Keystore:', KEYSTORE_PATH);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
async function cmdEnroll() {
|
|
98
|
+
const client = new AgentIDClient({ serverUrl: SERVER_URL, keystorePath: KEYSTORE_PATH });
|
|
99
|
+
|
|
100
|
+
const name = args[1] || process.env.AGENT_NAME;
|
|
101
|
+
const framework = args[2] || process.env.AGENT_FRAMEWORK || 'openclaw';
|
|
102
|
+
|
|
103
|
+
try {
|
|
104
|
+
await client.init();
|
|
105
|
+
const result = await client.enroll({ name, framework });
|
|
106
|
+
|
|
107
|
+
if (result.already_enrolled) {
|
|
108
|
+
console.log('✓ Already enrolled');
|
|
109
|
+
} else {
|
|
110
|
+
console.log('✓ Enrolled successfully');
|
|
111
|
+
}
|
|
112
|
+
console.log(' Agent ID:', result.agent_id);
|
|
113
|
+
console.log(' Enrolled:', result.enrolled_at);
|
|
114
|
+
} catch (error) {
|
|
115
|
+
console.error('Enrollment failed:', error.message);
|
|
116
|
+
process.exit(1);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
async function cmdVerify() {
|
|
121
|
+
const challenge = args[1];
|
|
122
|
+
|
|
123
|
+
if (!challenge) {
|
|
124
|
+
console.error('Usage: agentid verify <challenge>');
|
|
125
|
+
process.exit(1);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const client = new AgentIDClient({ serverUrl: SERVER_URL, keystorePath: KEYSTORE_PATH });
|
|
129
|
+
|
|
130
|
+
try {
|
|
131
|
+
await client.init();
|
|
132
|
+
const result = await client.verify(challenge);
|
|
133
|
+
|
|
134
|
+
if (result.valid) {
|
|
135
|
+
console.log('✓ Verification successful');
|
|
136
|
+
console.log(' Agent ID:', result.agent_id);
|
|
137
|
+
} else {
|
|
138
|
+
console.log('✗ Verification failed:', result.error);
|
|
139
|
+
}
|
|
140
|
+
} catch (error) {
|
|
141
|
+
console.error('Verification failed:', error.message);
|
|
142
|
+
process.exit(1);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
async function cmdCredentials() {
|
|
147
|
+
const client = new AgentIDClient({ serverUrl: SERVER_URL, keystorePath: KEYSTORE_PATH });
|
|
148
|
+
|
|
149
|
+
try {
|
|
150
|
+
await client.init();
|
|
151
|
+
const result = await client.getCredentials();
|
|
152
|
+
|
|
153
|
+
console.log('Agent ID:', result.agent_id);
|
|
154
|
+
console.log('Credentials:');
|
|
155
|
+
|
|
156
|
+
if (result.credentials.length === 0) {
|
|
157
|
+
console.log(' (none)');
|
|
158
|
+
} else {
|
|
159
|
+
for (const cred of result.credentials) {
|
|
160
|
+
console.log(` - ${cred.skill} [${cred.level}] (issued: ${cred.issued_at})`);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
} catch (error) {
|
|
164
|
+
console.error('Failed to fetch credentials:', error.message);
|
|
165
|
+
process.exit(1);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
function cmdExport() {
|
|
170
|
+
if (!existsSync(KEYSTORE_PATH)) {
|
|
171
|
+
console.error('No identity found. Run: agentid init');
|
|
172
|
+
process.exit(1);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const identity = JSON.parse(readFileSync(KEYSTORE_PATH, 'utf-8'));
|
|
176
|
+
|
|
177
|
+
const exportData = {
|
|
178
|
+
agent_id: identity.agentId,
|
|
179
|
+
pubkey: identity.publicKey
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
console.log(JSON.stringify(exportData, null, 2));
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
main().catch(console.error);
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# Congressional AI Framing Study - Final Report
|
|
2
|
+
|
|
3
|
+
**Date:** 2026-03-12
|
|
4
|
+
**Methodology:** CommDAAF multi-model validation
|
|
5
|
+
**Primary Coder:** Kimi K2.5
|
|
6
|
+
**Validation:** Claude Opus 4.5 (κ = 0.528, Moderate agreement)
|
|
7
|
+
|
|
8
|
+
## Data Summary
|
|
9
|
+
|
|
10
|
+
| Metric | Value |
|
|
11
|
+
|--------|-------|
|
|
12
|
+
| Source | GovInfo API (CHRG collection) |
|
|
13
|
+
| Query | "artificial intelligence" |
|
|
14
|
+
| Total collected | 561 transcripts |
|
|
15
|
+
| Valid AI hearings | 193 (filtered by AI density) |
|
|
16
|
+
| Successfully coded | 117 (60.6%) |
|
|
17
|
+
|
|
18
|
+
## Primary Frame Distribution
|
|
19
|
+
|
|
20
|
+
| Frame | Count | % | Description |
|
|
21
|
+
|-------|-------|---|-------------|
|
|
22
|
+
| GOVERNANCE | 26 | 22.2% | Regulatory approaches, oversight |
|
|
23
|
+
| INNOVATION | 24 | 20.5% | Economic opportunity, competitiveness |
|
|
24
|
+
| SOVEREIGNTY | 22 | 18.8% | National security, China competition |
|
|
25
|
+
| RISK_SAFETY | 15 | 12.8% | Existential/catastrophic threats |
|
|
26
|
+
| RISK_HARM | 12 | 10.3% | Concrete harms (bias, fraud) |
|
|
27
|
+
| RIGHTS | 10 | 8.5% | Privacy, civil rights |
|
|
28
|
+
| RISK_ECONOMIC | 6 | 5.1% | Job displacement |
|
|
29
|
+
| TECHNICAL | 2 | 1.7% | Scientific explanations |
|
|
30
|
+
|
|
31
|
+
## Temporal Trends
|
|
32
|
+
|
|
33
|
+
| Congress | Years | N | Dominant Frame | Interpretation |
|
|
34
|
+
|----------|-------|---|----------------|----------------|
|
|
35
|
+
| 114-115th | 2015-2018 | 5 | INNOVATION | Early AI optimism |
|
|
36
|
+
| 116-117th | 2019-2022 | 5 | Mixed | Emerging concerns |
|
|
37
|
+
| 118th | 2023-2024 | 75 | GOVERNANCE | Post-ChatGPT regulatory turn |
|
|
38
|
+
| 119th | 2025-2026 | 31 | INNOVATION | Deregulatory shift |
|
|
39
|
+
|
|
40
|
+
## Key Findings
|
|
41
|
+
|
|
42
|
+
### 1. Dual Dominant Framing
|
|
43
|
+
Congressional AI discourse is split between GOVERNANCE (regulatory) and INNOVATION (promotional) frames, with neither achieving clear dominance overall.
|
|
44
|
+
|
|
45
|
+
### 2. China Competition as Major Theme
|
|
46
|
+
SOVEREIGNTY framing (18.8%) reflects persistent concern about AI competition with China, appearing across Armed Services, Foreign Relations, and Commerce committees.
|
|
47
|
+
|
|
48
|
+
### 3. Risk Framing Diversity
|
|
49
|
+
Risk frames are differentiated:
|
|
50
|
+
- RISK_SAFETY (12.8%): Existential concerns, AI safety
|
|
51
|
+
- RISK_HARM (10.3%): Algorithmic bias, consumer fraud
|
|
52
|
+
- RISK_ECONOMIC (5.1%): Workforce displacement
|
|
53
|
+
|
|
54
|
+
### 4. Temporal Shift Pattern
|
|
55
|
+
Clear evolution from innovation optimism (2015-2018) to governance/regulatory focus (2023-2024), with potential return to innovation framing in 2025-2026 (possibly reflecting administration change).
|
|
56
|
+
|
|
57
|
+
### 5. Committee Specialization
|
|
58
|
+
- **Armed Services / Foreign Relations:** SOVEREIGNTY
|
|
59
|
+
- **Commerce / Consumer Protection:** RISK_HARM
|
|
60
|
+
- **Science & Technology:** INNOVATION
|
|
61
|
+
- **Judiciary:** GOVERNANCE (IP, oversight)
|
|
62
|
+
|
|
63
|
+
## Inter-Model Reliability
|
|
64
|
+
|
|
65
|
+
| Comparison | N | Agreement | Cohen's κ |
|
|
66
|
+
|------------|---|-----------|-----------|
|
|
67
|
+
| Pilot (Claude-GLM-Kimi) | 5 | 80% | 0.833 |
|
|
68
|
+
| Full (Claude-Kimi, B1-2) | 49 | 61% | 0.528 |
|
|
69
|
+
|
|
70
|
+
Interpretation: Moderate agreement, acceptable for exploratory research.
|
|
71
|
+
|
|
72
|
+
## Limitations
|
|
73
|
+
|
|
74
|
+
1. **Coverage:** 117/193 hearings coded (token limits on batches 3, 4, 6)
|
|
75
|
+
2. **Single primary coder:** Kimi K2.5 (Claude used defaults for low-density batches)
|
|
76
|
+
3. **GLM unavailable:** Rate limiting prevented 3-model validation at scale
|
|
77
|
+
4. **Temporal imbalance:** 118th Congress overrepresented (64% of sample)
|
|
78
|
+
|
|
79
|
+
## Files
|
|
80
|
+
|
|
81
|
+
- Raw data: `data/transcripts/` (561 files)
|
|
82
|
+
- Valid hearings: `data/valid_ai_hearings.json` (193 IDs)
|
|
83
|
+
- Kimi codings: `outputs/kimi/batch_*_kimi.json`
|
|
84
|
+
- Claude codings: `outputs/claude/batch_*_claude.json`
|
|
85
|
+
- Pilot comparison: `outputs/merged/pilot_filtered_5_comparison.md`
|
|
86
|
+
|
|
87
|
+
## Next Steps
|
|
88
|
+
|
|
89
|
+
1. Code remaining hearings (batches 3, 4, 6) with smaller chunks
|
|
90
|
+
2. Retry GLM with sequential (not parallel) requests
|
|
91
|
+
3. Formal regression analysis: frame ~ congress + committee + party
|
|
92
|
+
4. Cross-validate with human coders on random sample
|
|
93
|
+
5. Extend to 119th Congress as hearings become available
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
*Generated by OpenClaw CommDAAF multi-model validation system*
|