@tjamescouch/agentchat 0.10.0 → 0.12.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/bin/agentchat.js +192 -4
- package/lib/client.js +137 -4
- package/lib/elo_swarm.py +569 -0
- package/lib/escrow-hooks.js +237 -0
- package/lib/identity.js +134 -2
- package/lib/proposals.js +33 -8
- package/lib/protocol.js +115 -6
- package/lib/reputation.js +214 -14
- package/lib/server-directory.js +181 -0
- package/lib/server.js +368 -19
- package/package.json +1 -1
package/bin/agentchat.js
CHANGED
|
@@ -48,6 +48,10 @@ import {
|
|
|
48
48
|
DEFAULT_RATINGS_PATH,
|
|
49
49
|
DEFAULT_RATING
|
|
50
50
|
} from '../lib/reputation.js';
|
|
51
|
+
import {
|
|
52
|
+
ServerDirectory,
|
|
53
|
+
DEFAULT_DIRECTORY_PATH
|
|
54
|
+
} from '../lib/server-directory.js';
|
|
51
55
|
|
|
52
56
|
program
|
|
53
57
|
.name('agentchat')
|
|
@@ -95,7 +99,11 @@ program
|
|
|
95
99
|
console.log('Message sent');
|
|
96
100
|
process.exit(0);
|
|
97
101
|
} catch (err) {
|
|
98
|
-
|
|
102
|
+
if (err.code === 'ECONNREFUSED') {
|
|
103
|
+
console.error('Error: Connection refused. Is the server running?');
|
|
104
|
+
} else {
|
|
105
|
+
console.error('Error:', err.message || err.code || err);
|
|
106
|
+
}
|
|
99
107
|
process.exit(1);
|
|
100
108
|
}
|
|
101
109
|
});
|
|
@@ -142,7 +150,12 @@ program
|
|
|
142
150
|
});
|
|
143
151
|
|
|
144
152
|
} catch (err) {
|
|
145
|
-
|
|
153
|
+
if (err.code === 'ECONNREFUSED') {
|
|
154
|
+
console.error('Error: Connection refused. Is the server running?');
|
|
155
|
+
console.error(` Try: agentchat serve --port 8080`);
|
|
156
|
+
} else {
|
|
157
|
+
console.error('Error:', err.message || err.code || err);
|
|
158
|
+
}
|
|
146
159
|
process.exit(1);
|
|
147
160
|
}
|
|
148
161
|
});
|
|
@@ -358,6 +371,7 @@ program
|
|
|
358
371
|
.option('-p, --payment-code <code>', 'Your payment code (BIP47, address)')
|
|
359
372
|
.option('-e, --expires <seconds>', 'Expiration time in seconds', '300')
|
|
360
373
|
.option('-t, --terms <terms>', 'Additional terms')
|
|
374
|
+
.option('-s, --elo-stake <n>', 'ELO points to stake on this proposal')
|
|
361
375
|
.action(async (server, agent, task, options) => {
|
|
362
376
|
try {
|
|
363
377
|
const client = new AgentChatClient({ server, identity: options.identity });
|
|
@@ -369,7 +383,8 @@ program
|
|
|
369
383
|
currency: options.currency,
|
|
370
384
|
payment_code: options.paymentCode,
|
|
371
385
|
terms: options.terms,
|
|
372
|
-
expires: parseInt(options.expires)
|
|
386
|
+
expires: parseInt(options.expires),
|
|
387
|
+
elo_stake: options.eloStake ? parseInt(options.eloStake) : undefined
|
|
373
388
|
});
|
|
374
389
|
|
|
375
390
|
console.log('Proposal sent:');
|
|
@@ -377,6 +392,7 @@ program
|
|
|
377
392
|
console.log(` To: ${proposal.to}`);
|
|
378
393
|
console.log(` Task: ${proposal.task}`);
|
|
379
394
|
if (proposal.amount) console.log(` Amount: ${proposal.amount} ${proposal.currency || ''}`);
|
|
395
|
+
if (proposal.elo_stake) console.log(` ELO Stake: ${proposal.elo_stake}`);
|
|
380
396
|
if (proposal.expires) console.log(` Expires: ${new Date(proposal.expires).toISOString()}`);
|
|
381
397
|
console.log(`\nUse this ID to track responses.`);
|
|
382
398
|
|
|
@@ -394,16 +410,20 @@ program
|
|
|
394
410
|
.description('Accept a proposal')
|
|
395
411
|
.option('-i, --identity <file>', 'Path to identity file (required)', DEFAULT_IDENTITY_PATH)
|
|
396
412
|
.option('-p, --payment-code <code>', 'Your payment code for receiving payment')
|
|
413
|
+
.option('-s, --elo-stake <n>', 'ELO points to stake (as acceptor)')
|
|
397
414
|
.action(async (server, proposalId, options) => {
|
|
398
415
|
try {
|
|
399
416
|
const client = new AgentChatClient({ server, identity: options.identity });
|
|
400
417
|
await client.connect();
|
|
401
418
|
|
|
402
|
-
const
|
|
419
|
+
const eloStake = options.eloStake ? parseInt(options.eloStake) : undefined;
|
|
420
|
+
const response = await client.accept(proposalId, options.paymentCode, eloStake);
|
|
403
421
|
|
|
404
422
|
console.log('Proposal accepted:');
|
|
405
423
|
console.log(` Proposal ID: ${response.proposal_id}`);
|
|
406
424
|
console.log(` Status: ${response.status}`);
|
|
425
|
+
if (response.proposer_stake) console.log(` Proposer Stake: ${response.proposer_stake} ELO`);
|
|
426
|
+
if (response.acceptor_stake) console.log(` Your Stake: ${response.acceptor_stake} ELO`);
|
|
407
427
|
|
|
408
428
|
client.disconnect();
|
|
409
429
|
process.exit(0);
|
|
@@ -488,6 +508,39 @@ program
|
|
|
488
508
|
}
|
|
489
509
|
});
|
|
490
510
|
|
|
511
|
+
// Verify agent identity command
|
|
512
|
+
program
|
|
513
|
+
.command('verify <server> <agent>')
|
|
514
|
+
.description('Verify another agent\'s identity via challenge-response')
|
|
515
|
+
.option('-i, --identity <file>', 'Path to identity file (required)', DEFAULT_IDENTITY_PATH)
|
|
516
|
+
.action(async (server, agent, options) => {
|
|
517
|
+
try {
|
|
518
|
+
const client = new AgentChatClient({ server, identity: options.identity });
|
|
519
|
+
await client.connect();
|
|
520
|
+
|
|
521
|
+
console.log(`Verifying identity of ${agent}...`);
|
|
522
|
+
|
|
523
|
+
const result = await client.verify(agent);
|
|
524
|
+
|
|
525
|
+
if (result.verified) {
|
|
526
|
+
console.log('Identity verified!');
|
|
527
|
+
console.log(` Agent: ${result.agent}`);
|
|
528
|
+
console.log(` Public Key:`);
|
|
529
|
+
console.log(result.pubkey.split('\n').map(line => ` ${line}`).join('\n'));
|
|
530
|
+
} else {
|
|
531
|
+
console.log('Verification failed!');
|
|
532
|
+
console.log(` Target: ${result.target}`);
|
|
533
|
+
console.log(` Reason: ${result.reason}`);
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
client.disconnect();
|
|
537
|
+
process.exit(result.verified ? 0 : 1);
|
|
538
|
+
} catch (err) {
|
|
539
|
+
console.error('Error:', err.message);
|
|
540
|
+
process.exit(1);
|
|
541
|
+
}
|
|
542
|
+
});
|
|
543
|
+
|
|
491
544
|
// Identity management command
|
|
492
545
|
program
|
|
493
546
|
.command('identity')
|
|
@@ -495,6 +548,8 @@ program
|
|
|
495
548
|
.option('-g, --generate', 'Generate new keypair')
|
|
496
549
|
.option('-s, --show', 'Show current identity')
|
|
497
550
|
.option('-e, --export', 'Export public key for sharing (JSON to stdout)')
|
|
551
|
+
.option('-r, --rotate', 'Rotate to new keypair (signs new key with old key)')
|
|
552
|
+
.option('--verify-chain', 'Verify the rotation chain')
|
|
498
553
|
.option('-f, --file <path>', 'Identity file path', DEFAULT_IDENTITY_PATH)
|
|
499
554
|
.option('-n, --name <name>', 'Agent name (for --generate)', `agent-${process.pid}`)
|
|
500
555
|
.option('--force', 'Overwrite existing identity')
|
|
@@ -535,6 +590,54 @@ program
|
|
|
535
590
|
const identity = await Identity.load(options.file);
|
|
536
591
|
console.log(JSON.stringify(identity.export(), null, 2));
|
|
537
592
|
|
|
593
|
+
} else if (options.rotate) {
|
|
594
|
+
// Rotate to new keypair
|
|
595
|
+
const identity = await Identity.load(options.file);
|
|
596
|
+
const oldAgentId = identity.getAgentId();
|
|
597
|
+
const oldFingerprint = identity.getFingerprint();
|
|
598
|
+
|
|
599
|
+
console.log('Rotating identity...');
|
|
600
|
+
console.log(` Old Agent ID: ${oldAgentId}`);
|
|
601
|
+
console.log(` Old Fingerprint: ${oldFingerprint}`);
|
|
602
|
+
|
|
603
|
+
const record = identity.rotate();
|
|
604
|
+
await identity.save(options.file);
|
|
605
|
+
|
|
606
|
+
console.log('');
|
|
607
|
+
console.log('Rotation complete:');
|
|
608
|
+
console.log(` New Agent ID: ${identity.getAgentId()}`);
|
|
609
|
+
console.log(` New Fingerprint: ${identity.getFingerprint()}`);
|
|
610
|
+
console.log(` Total rotations: ${identity.rotations.length}`);
|
|
611
|
+
console.log('');
|
|
612
|
+
console.log('The new key has been signed by the old key for chain of custody.');
|
|
613
|
+
console.log('Share the rotation record to prove key continuity.');
|
|
614
|
+
|
|
615
|
+
} else if (options.verifyChain) {
|
|
616
|
+
// Verify rotation chain
|
|
617
|
+
const identity = await Identity.load(options.file);
|
|
618
|
+
|
|
619
|
+
if (identity.rotations.length === 0) {
|
|
620
|
+
console.log('No rotations to verify (original identity).');
|
|
621
|
+
console.log(` Agent ID: ${identity.getAgentId()}`);
|
|
622
|
+
process.exit(0);
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
console.log(`Verifying rotation chain (${identity.rotations.length} rotation(s))...`);
|
|
626
|
+
const result = identity.verifyRotationChain();
|
|
627
|
+
|
|
628
|
+
if (result.valid) {
|
|
629
|
+
console.log('Chain verified successfully!');
|
|
630
|
+
console.log(` Original Agent ID: ${identity.getOriginalAgentId()}`);
|
|
631
|
+
console.log(` Current Agent ID: ${identity.getAgentId()}`);
|
|
632
|
+
console.log(` Rotations: ${identity.rotations.length}`);
|
|
633
|
+
} else {
|
|
634
|
+
console.error('Chain verification FAILED:');
|
|
635
|
+
for (const error of result.errors) {
|
|
636
|
+
console.error(` - ${error}`);
|
|
637
|
+
}
|
|
638
|
+
process.exit(1);
|
|
639
|
+
}
|
|
640
|
+
|
|
538
641
|
} else {
|
|
539
642
|
// Default: show if exists, otherwise show help
|
|
540
643
|
const exists = await Identity.exists(options.file);
|
|
@@ -1101,6 +1204,91 @@ program
|
|
|
1101
1204
|
}
|
|
1102
1205
|
});
|
|
1103
1206
|
|
|
1207
|
+
// Discover command - find public AgentChat servers
|
|
1208
|
+
program
|
|
1209
|
+
.command('discover')
|
|
1210
|
+
.description('Discover available AgentChat servers')
|
|
1211
|
+
.option('--add <url>', 'Add a server to the directory')
|
|
1212
|
+
.option('--remove <url>', 'Remove a server from the directory')
|
|
1213
|
+
.option('--name <name>', 'Server name (for --add)')
|
|
1214
|
+
.option('--description <desc>', 'Server description (for --add)')
|
|
1215
|
+
.option('--region <region>', 'Server region (for --add)')
|
|
1216
|
+
.option('--online', 'Only show online servers')
|
|
1217
|
+
.option('--json', 'Output as JSON')
|
|
1218
|
+
.option('--no-check', 'List servers without health check')
|
|
1219
|
+
.option('--directory <path>', 'Custom directory file path', DEFAULT_DIRECTORY_PATH)
|
|
1220
|
+
.action(async (options) => {
|
|
1221
|
+
try {
|
|
1222
|
+
const directory = new ServerDirectory({ directoryPath: options.directory });
|
|
1223
|
+
await directory.load();
|
|
1224
|
+
|
|
1225
|
+
// Add server
|
|
1226
|
+
if (options.add) {
|
|
1227
|
+
await directory.addServer({
|
|
1228
|
+
url: options.add,
|
|
1229
|
+
name: options.name || options.add,
|
|
1230
|
+
description: options.description || '',
|
|
1231
|
+
region: options.region || 'unknown'
|
|
1232
|
+
});
|
|
1233
|
+
console.log(`Added server: ${options.add}`);
|
|
1234
|
+
process.exit(0);
|
|
1235
|
+
}
|
|
1236
|
+
|
|
1237
|
+
// Remove server
|
|
1238
|
+
if (options.remove) {
|
|
1239
|
+
await directory.removeServer(options.remove);
|
|
1240
|
+
console.log(`Removed server: ${options.remove}`);
|
|
1241
|
+
process.exit(0);
|
|
1242
|
+
}
|
|
1243
|
+
|
|
1244
|
+
// List/discover servers
|
|
1245
|
+
let servers;
|
|
1246
|
+
if (options.check === false) {
|
|
1247
|
+
servers = directory.list().map(s => ({ ...s, status: 'unknown' }));
|
|
1248
|
+
} else {
|
|
1249
|
+
console.error('Checking server status...');
|
|
1250
|
+
servers = await directory.discover({ onlineOnly: options.online });
|
|
1251
|
+
}
|
|
1252
|
+
|
|
1253
|
+
if (options.json) {
|
|
1254
|
+
console.log(JSON.stringify(servers, null, 2));
|
|
1255
|
+
} else {
|
|
1256
|
+
if (servers.length === 0) {
|
|
1257
|
+
console.log('No servers found.');
|
|
1258
|
+
} else {
|
|
1259
|
+
console.log(`\nFound ${servers.length} server(s):\n`);
|
|
1260
|
+
for (const server of servers) {
|
|
1261
|
+
const statusIcon = server.status === 'online' ? '\u2713' :
|
|
1262
|
+
server.status === 'offline' ? '\u2717' : '?';
|
|
1263
|
+
console.log(` ${statusIcon} ${server.name}`);
|
|
1264
|
+
console.log(` URL: ${server.url}`);
|
|
1265
|
+
console.log(` Status: ${server.status}`);
|
|
1266
|
+
if (server.description) {
|
|
1267
|
+
console.log(` Description: ${server.description}`);
|
|
1268
|
+
}
|
|
1269
|
+
if (server.region) {
|
|
1270
|
+
console.log(` Region: ${server.region}`);
|
|
1271
|
+
}
|
|
1272
|
+
if (server.health) {
|
|
1273
|
+
console.log(` Agents: ${server.health.agents?.connected || 0}`);
|
|
1274
|
+
console.log(` Uptime: ${server.health.uptime_seconds || 0}s`);
|
|
1275
|
+
}
|
|
1276
|
+
if (server.error) {
|
|
1277
|
+
console.log(` Error: ${server.error}`);
|
|
1278
|
+
}
|
|
1279
|
+
console.log('');
|
|
1280
|
+
}
|
|
1281
|
+
}
|
|
1282
|
+
console.log(`Directory: ${options.directory}`);
|
|
1283
|
+
}
|
|
1284
|
+
|
|
1285
|
+
process.exit(0);
|
|
1286
|
+
} catch (err) {
|
|
1287
|
+
console.error('Error:', err.message);
|
|
1288
|
+
process.exit(1);
|
|
1289
|
+
}
|
|
1290
|
+
});
|
|
1291
|
+
|
|
1104
1292
|
// Deploy command
|
|
1105
1293
|
program
|
|
1106
1294
|
.command('deploy')
|
package/lib/client.js
CHANGED
|
@@ -10,7 +10,8 @@ import {
|
|
|
10
10
|
ServerMessageType,
|
|
11
11
|
createMessage,
|
|
12
12
|
serialize,
|
|
13
|
-
parse
|
|
13
|
+
parse,
|
|
14
|
+
generateNonce
|
|
14
15
|
} from './protocol.js';
|
|
15
16
|
import { Identity } from './identity.js';
|
|
16
17
|
import {
|
|
@@ -297,7 +298,8 @@ export class AgentChatClient extends EventEmitter {
|
|
|
297
298
|
currency: proposal.currency,
|
|
298
299
|
payment_code: proposal.payment_code,
|
|
299
300
|
terms: proposal.terms,
|
|
300
|
-
expires: proposal.expires
|
|
301
|
+
expires: proposal.expires,
|
|
302
|
+
elo_stake: proposal.elo_stake
|
|
301
303
|
};
|
|
302
304
|
|
|
303
305
|
// Sign the proposal
|
|
@@ -337,19 +339,21 @@ export class AgentChatClient extends EventEmitter {
|
|
|
337
339
|
* Accept a proposal
|
|
338
340
|
* @param {string} proposalId - The proposal ID to accept
|
|
339
341
|
* @param {string} [payment_code] - Your payment code for receiving payment
|
|
342
|
+
* @param {number} [elo_stake] - ELO points to stake as acceptor
|
|
340
343
|
*/
|
|
341
|
-
async accept(proposalId, payment_code = null) {
|
|
344
|
+
async accept(proposalId, payment_code = null, elo_stake = null) {
|
|
342
345
|
if (!this._identity || !this._identity.privkey) {
|
|
343
346
|
throw new Error('Accepting proposals requires persistent identity.');
|
|
344
347
|
}
|
|
345
348
|
|
|
346
|
-
const sigContent = getAcceptSigningContent(proposalId, payment_code || '');
|
|
349
|
+
const sigContent = getAcceptSigningContent(proposalId, payment_code || '', elo_stake || '');
|
|
347
350
|
const sig = this._identity.sign(sigContent);
|
|
348
351
|
|
|
349
352
|
const msg = {
|
|
350
353
|
type: ClientMessageType.ACCEPT,
|
|
351
354
|
proposal_id: proposalId,
|
|
352
355
|
payment_code,
|
|
356
|
+
elo_stake,
|
|
353
357
|
sig
|
|
354
358
|
};
|
|
355
359
|
|
|
@@ -529,6 +533,118 @@ export class AgentChatClient extends EventEmitter {
|
|
|
529
533
|
});
|
|
530
534
|
}
|
|
531
535
|
|
|
536
|
+
// ===== IDENTITY VERIFICATION METHODS =====
|
|
537
|
+
|
|
538
|
+
/**
|
|
539
|
+
* Request identity verification from another agent
|
|
540
|
+
* Sends a challenge nonce that the target must sign to prove they control their identity
|
|
541
|
+
* @param {string} target - Target agent to verify (@id)
|
|
542
|
+
* @returns {Promise<object>} Verification result with pubkey if successful
|
|
543
|
+
*/
|
|
544
|
+
async verify(target) {
|
|
545
|
+
const targetAgent = target.startsWith('@') ? target : `@${target}`;
|
|
546
|
+
const nonce = generateNonce();
|
|
547
|
+
|
|
548
|
+
const msg = {
|
|
549
|
+
type: ClientMessageType.VERIFY_REQUEST,
|
|
550
|
+
target: targetAgent,
|
|
551
|
+
nonce
|
|
552
|
+
};
|
|
553
|
+
|
|
554
|
+
this._send(msg);
|
|
555
|
+
|
|
556
|
+
return new Promise((resolve, reject) => {
|
|
557
|
+
const timeout = setTimeout(() => {
|
|
558
|
+
this.removeListener('verify_success', onSuccess);
|
|
559
|
+
this.removeListener('verify_failed', onFailed);
|
|
560
|
+
this.removeListener('error', onError);
|
|
561
|
+
reject(new Error('Verification timeout'));
|
|
562
|
+
}, 35000); // Slightly longer than server timeout
|
|
563
|
+
|
|
564
|
+
const onSuccess = (response) => {
|
|
565
|
+
if (response.agent === targetAgent || response.target === targetAgent) {
|
|
566
|
+
clearTimeout(timeout);
|
|
567
|
+
this.removeListener('verify_failed', onFailed);
|
|
568
|
+
this.removeListener('error', onError);
|
|
569
|
+
resolve({
|
|
570
|
+
verified: true,
|
|
571
|
+
agent: response.agent,
|
|
572
|
+
pubkey: response.pubkey,
|
|
573
|
+
request_id: response.request_id
|
|
574
|
+
});
|
|
575
|
+
}
|
|
576
|
+
};
|
|
577
|
+
|
|
578
|
+
const onFailed = (response) => {
|
|
579
|
+
if (response.target === targetAgent) {
|
|
580
|
+
clearTimeout(timeout);
|
|
581
|
+
this.removeListener('verify_success', onSuccess);
|
|
582
|
+
this.removeListener('error', onError);
|
|
583
|
+
resolve({
|
|
584
|
+
verified: false,
|
|
585
|
+
target: response.target,
|
|
586
|
+
reason: response.reason,
|
|
587
|
+
request_id: response.request_id
|
|
588
|
+
});
|
|
589
|
+
}
|
|
590
|
+
};
|
|
591
|
+
|
|
592
|
+
const onError = (err) => {
|
|
593
|
+
clearTimeout(timeout);
|
|
594
|
+
this.removeListener('verify_success', onSuccess);
|
|
595
|
+
this.removeListener('verify_failed', onFailed);
|
|
596
|
+
reject(new Error(err.message));
|
|
597
|
+
};
|
|
598
|
+
|
|
599
|
+
this.on('verify_success', onSuccess);
|
|
600
|
+
this.on('verify_failed', onFailed);
|
|
601
|
+
this.once('error', onError);
|
|
602
|
+
});
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
/**
|
|
606
|
+
* Respond to a verification request by signing the nonce
|
|
607
|
+
* This is typically called automatically when a VERIFY_REQUEST is received
|
|
608
|
+
* @param {string} requestId - The verification request ID
|
|
609
|
+
* @param {string} nonce - The nonce to sign
|
|
610
|
+
*/
|
|
611
|
+
async respondToVerification(requestId, nonce) {
|
|
612
|
+
if (!this._identity || !this._identity.privkey) {
|
|
613
|
+
throw new Error('Responding to verification requires persistent identity.');
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
const sig = this._identity.sign(nonce);
|
|
617
|
+
|
|
618
|
+
const msg = {
|
|
619
|
+
type: ClientMessageType.VERIFY_RESPONSE,
|
|
620
|
+
request_id: requestId,
|
|
621
|
+
nonce,
|
|
622
|
+
sig
|
|
623
|
+
};
|
|
624
|
+
|
|
625
|
+
this._send(msg);
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
/**
|
|
629
|
+
* Enable automatic verification response
|
|
630
|
+
* When enabled, the client will automatically respond to VERIFY_REQUEST messages
|
|
631
|
+
* @param {boolean} enabled - Whether to enable auto-response
|
|
632
|
+
*/
|
|
633
|
+
enableAutoVerification(enabled = true) {
|
|
634
|
+
if (enabled) {
|
|
635
|
+
this._autoVerifyHandler = (msg) => {
|
|
636
|
+
if (msg.request_id && msg.nonce && msg.from) {
|
|
637
|
+
this.respondToVerification(msg.request_id, msg.nonce)
|
|
638
|
+
.catch(err => this.emit('error', { message: `Auto-verification failed: ${err.message}` }));
|
|
639
|
+
}
|
|
640
|
+
};
|
|
641
|
+
this.on('verify_request', this._autoVerifyHandler);
|
|
642
|
+
} else if (this._autoVerifyHandler) {
|
|
643
|
+
this.removeListener('verify_request', this._autoVerifyHandler);
|
|
644
|
+
this._autoVerifyHandler = null;
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
|
|
532
648
|
_send(msg) {
|
|
533
649
|
if (this.ws && this.ws.readyState === WebSocket.OPEN) {
|
|
534
650
|
this.ws.send(serialize(msg));
|
|
@@ -627,6 +743,23 @@ export class AgentChatClient extends EventEmitter {
|
|
|
627
743
|
this.emit('search_results', msg);
|
|
628
744
|
this.emit('message', msg);
|
|
629
745
|
break;
|
|
746
|
+
|
|
747
|
+
// Identity verification messages
|
|
748
|
+
case ServerMessageType.VERIFY_REQUEST:
|
|
749
|
+
this.emit('verify_request', msg);
|
|
750
|
+
break;
|
|
751
|
+
|
|
752
|
+
case ServerMessageType.VERIFY_RESPONSE:
|
|
753
|
+
this.emit('verify_response', msg);
|
|
754
|
+
break;
|
|
755
|
+
|
|
756
|
+
case ServerMessageType.VERIFY_SUCCESS:
|
|
757
|
+
this.emit('verify_success', msg);
|
|
758
|
+
break;
|
|
759
|
+
|
|
760
|
+
case ServerMessageType.VERIFY_FAILED:
|
|
761
|
+
this.emit('verify_failed', msg);
|
|
762
|
+
break;
|
|
630
763
|
}
|
|
631
764
|
}
|
|
632
765
|
}
|