@tjamescouch/agentchat 0.36.2 → 0.36.4
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 +20 -15
- package/dist/bin/agentchat.js +2 -0
- package/dist/bin/agentchat.js.map +1 -1
- package/dist/lib/captcha.d.ts +36 -0
- package/dist/lib/captcha.d.ts.map +1 -0
- package/dist/lib/captcha.js +215 -0
- package/dist/lib/captcha.js.map +1 -0
- package/dist/lib/client.d.ts +8 -0
- package/dist/lib/client.d.ts.map +1 -1
- package/dist/lib/client.js +118 -0
- package/dist/lib/client.js.map +1 -1
- package/dist/lib/daemon.d.ts +2 -0
- package/dist/lib/daemon.d.ts.map +1 -1
- package/dist/lib/daemon.js +6 -0
- package/dist/lib/daemon.js.map +1 -1
- package/dist/lib/env-doctor.d.ts +50 -0
- package/dist/lib/env-doctor.d.ts.map +1 -0
- package/dist/lib/env-doctor.js +209 -0
- package/dist/lib/env-doctor.js.map +1 -0
- package/dist/lib/hnsw.d.ts +91 -0
- package/dist/lib/hnsw.d.ts.map +1 -0
- package/dist/lib/hnsw.js +486 -0
- package/dist/lib/hnsw.js.map +1 -0
- package/dist/lib/proposals.d.ts +2 -0
- package/dist/lib/proposals.d.ts.map +1 -1
- package/dist/lib/proposals.js +1 -0
- package/dist/lib/proposals.js.map +1 -1
- package/dist/lib/protocol.d.ts +14 -0
- package/dist/lib/protocol.d.ts.map +1 -1
- package/dist/lib/protocol.js +37 -0
- package/dist/lib/protocol.js.map +1 -1
- package/dist/lib/reputation.d.ts +34 -0
- package/dist/lib/reputation.d.ts.map +1 -1
- package/dist/lib/reputation.js +128 -0
- package/dist/lib/reputation.js.map +1 -1
- package/dist/lib/server/handlers/admin.d.ts +10 -7
- package/dist/lib/server/handlers/admin.d.ts.map +1 -1
- package/dist/lib/server/handlers/admin.js +73 -0
- package/dist/lib/server/handlers/admin.js.map +1 -1
- package/dist/lib/server/handlers/ban.d.ts +1 -7
- package/dist/lib/server/handlers/ban.d.ts.map +1 -1
- package/dist/lib/server/handlers/ban.js.map +1 -1
- package/dist/lib/server/handlers/captcha.d.ts +49 -0
- package/dist/lib/server/handlers/captcha.d.ts.map +1 -0
- package/dist/lib/server/handlers/captcha.js +203 -0
- package/dist/lib/server/handlers/captcha.js.map +1 -0
- package/dist/lib/server/handlers/disputes.d.ts +1 -7
- package/dist/lib/server/handlers/disputes.d.ts.map +1 -1
- package/dist/lib/server/handlers/disputes.js.map +1 -1
- package/dist/lib/server/handlers/identity.d.ts +1 -7
- package/dist/lib/server/handlers/identity.d.ts.map +1 -1
- package/dist/lib/server/handlers/identity.js +67 -11
- package/dist/lib/server/handlers/identity.js.map +1 -1
- package/dist/lib/server/handlers/index.d.ts +1 -0
- package/dist/lib/server/handlers/index.d.ts.map +1 -1
- package/dist/lib/server/handlers/index.js +2 -0
- package/dist/lib/server/handlers/index.js.map +1 -1
- package/dist/lib/server/handlers/message.d.ts +1 -7
- package/dist/lib/server/handlers/message.d.ts.map +1 -1
- package/dist/lib/server/handlers/message.js +9 -2
- package/dist/lib/server/handlers/message.js.map +1 -1
- package/dist/lib/server/handlers/nick.d.ts +1 -8
- package/dist/lib/server/handlers/nick.d.ts.map +1 -1
- package/dist/lib/server/handlers/nick.js.map +1 -1
- package/dist/lib/server/handlers/presence.d.ts +1 -7
- package/dist/lib/server/handlers/presence.d.ts.map +1 -1
- package/dist/lib/server/handlers/presence.js.map +1 -1
- package/dist/lib/server/handlers/proposal.d.ts +1 -7
- package/dist/lib/server/handlers/proposal.d.ts.map +1 -1
- package/dist/lib/server/handlers/proposal.js +1 -0
- package/dist/lib/server/handlers/proposal.js.map +1 -1
- package/dist/lib/server/handlers/skills.d.ts +1 -7
- package/dist/lib/server/handlers/skills.d.ts.map +1 -1
- package/dist/lib/server/handlers/skills.js +36 -11
- package/dist/lib/server/handlers/skills.js.map +1 -1
- package/dist/lib/server.d.ts +35 -1
- package/dist/lib/server.d.ts.map +1 -1
- package/dist/lib/server.js +152 -13
- package/dist/lib/server.js.map +1 -1
- package/dist/lib/types.d.ts +34 -4
- package/dist/lib/types.d.ts.map +1 -1
- package/dist/lib/types.js +8 -0
- package/dist/lib/types.js.map +1 -1
- package/package.json +2 -1
|
@@ -111,25 +111,50 @@ export async function handleSearchSkills(server, ws, msg) {
|
|
|
111
111
|
}
|
|
112
112
|
}
|
|
113
113
|
}
|
|
114
|
-
// Enrich results with reputation data
|
|
114
|
+
// Enrich results with agent + skill-specific reputation data
|
|
115
115
|
const uniqueAgentIds = [...new Set(results.map(r => r.agent_id))];
|
|
116
|
-
const
|
|
116
|
+
const agentRatingCache = new Map();
|
|
117
|
+
const skillRatingCache = new Map();
|
|
117
118
|
for (const agentId of uniqueAgentIds) {
|
|
118
|
-
|
|
119
|
-
|
|
119
|
+
// Get agent-level rating
|
|
120
|
+
const agentRatingInfo = await server.reputationStore.getRating(agentId);
|
|
121
|
+
agentRatingCache.set(agentId, agentRatingInfo);
|
|
122
|
+
}
|
|
123
|
+
// For each result, also get skill-specific rating
|
|
124
|
+
for (const result of results) {
|
|
125
|
+
const agentIdNormalized = result.agent_id.replace('@', '');
|
|
126
|
+
// Get skill-specific rating
|
|
127
|
+
const skillRatingInfo = await server.reputationStore.getRatingForSkill(agentIdNormalized, result.capability);
|
|
128
|
+
const cacheKey = `${agentIdNormalized}:${result.capability}`;
|
|
129
|
+
skillRatingCache.set(cacheKey, {
|
|
130
|
+
capability: result.capability,
|
|
131
|
+
...skillRatingInfo
|
|
132
|
+
});
|
|
120
133
|
}
|
|
121
134
|
// Add rating info to each result
|
|
122
135
|
for (const result of results) {
|
|
123
|
-
const
|
|
124
|
-
if (
|
|
125
|
-
result.
|
|
126
|
-
result.
|
|
136
|
+
const agentRatingInfo = agentRatingCache.get(result.agent_id);
|
|
137
|
+
if (agentRatingInfo) {
|
|
138
|
+
result.agent_rating = agentRatingInfo.rating;
|
|
139
|
+
result.agent_transactions = agentRatingInfo.transactions;
|
|
140
|
+
}
|
|
141
|
+
const agentIdNormalized = result.agent_id.replace('@', '');
|
|
142
|
+
const cacheKey = `${agentIdNormalized}:${result.capability}`;
|
|
143
|
+
const skillRatingInfo = skillRatingCache.get(cacheKey);
|
|
144
|
+
if (skillRatingInfo) {
|
|
145
|
+
result.skill_rating = skillRatingInfo.rating;
|
|
146
|
+
result.skill_transactions = skillRatingInfo.transactions;
|
|
147
|
+
result.skill_updated = skillRatingInfo.updated;
|
|
127
148
|
}
|
|
128
149
|
}
|
|
129
|
-
// Sort by rating (highest first), then by registration time
|
|
150
|
+
// Sort by skill rating (highest first), then agent rating, then by registration time
|
|
130
151
|
results.sort((a, b) => {
|
|
131
|
-
if ((b.
|
|
132
|
-
return (b.
|
|
152
|
+
if ((b.skill_rating || 0) !== (a.skill_rating || 0)) {
|
|
153
|
+
return (b.skill_rating || 0) - (a.skill_rating || 0);
|
|
154
|
+
}
|
|
155
|
+
if ((b.agent_rating || 0) !== (a.agent_rating || 0)) {
|
|
156
|
+
return (b.agent_rating || 0) - (a.agent_rating || 0);
|
|
157
|
+
}
|
|
133
158
|
return b.registered_at - a.registered_at;
|
|
134
159
|
});
|
|
135
160
|
// Limit results
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skills.js","sourceRoot":"","sources":["../../../../lib/server/handlers/skills.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"skills.js","sourceRoot":"","sources":["../../../../lib/server/handlers/skills.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/server.d.ts
CHANGED
|
@@ -16,12 +16,20 @@ import { Banlist } from './banlist.js';
|
|
|
16
16
|
import { Redactor } from './redactor.js';
|
|
17
17
|
import { CallbackQueue, type CallbackEntry } from './callback-engine.js';
|
|
18
18
|
import { FloorControl } from './floor-control.js';
|
|
19
|
-
|
|
19
|
+
import { CaptchaConfig } from './captcha.js';
|
|
20
|
+
export interface ExtendedWebSocket extends WebSocket {
|
|
20
21
|
_connectedAt?: number;
|
|
21
22
|
_realIp?: string;
|
|
23
|
+
_geoCountry?: string;
|
|
24
|
+
_geoCity?: string;
|
|
25
|
+
_geoLat?: number;
|
|
26
|
+
_geoLon?: number;
|
|
22
27
|
_userAgent?: string;
|
|
28
|
+
_connId?: string;
|
|
23
29
|
_msgTimestamps?: number[];
|
|
24
30
|
_isAlive?: boolean;
|
|
31
|
+
_lastPong?: number;
|
|
32
|
+
_lastNickChange?: number;
|
|
25
33
|
}
|
|
26
34
|
export interface AgentState {
|
|
27
35
|
id: string;
|
|
@@ -44,6 +52,21 @@ export interface PendingChallenge {
|
|
|
44
52
|
challengeId: string;
|
|
45
53
|
expires: number;
|
|
46
54
|
}
|
|
55
|
+
export interface PendingCaptcha {
|
|
56
|
+
ws: ExtendedWebSocket;
|
|
57
|
+
captchaId: string;
|
|
58
|
+
question: string;
|
|
59
|
+
answer: string;
|
|
60
|
+
alternates?: string[];
|
|
61
|
+
expires: number;
|
|
62
|
+
attempts: number;
|
|
63
|
+
name: string;
|
|
64
|
+
pubkey: string | null;
|
|
65
|
+
id: string | null;
|
|
66
|
+
isApproved: boolean;
|
|
67
|
+
isNew: boolean;
|
|
68
|
+
lurkUntil: number;
|
|
69
|
+
}
|
|
47
70
|
export interface ChannelState {
|
|
48
71
|
name: string;
|
|
49
72
|
inviteOnly: boolean;
|
|
@@ -78,6 +101,7 @@ export interface AgentChatServerOptions {
|
|
|
78
101
|
challengeTimeoutMs?: number;
|
|
79
102
|
logger?: Console;
|
|
80
103
|
escrowHandlers?: Record<string, (payload: unknown) => Promise<void>>;
|
|
104
|
+
genesisAgentId?: string | null;
|
|
81
105
|
allowlistEnabled?: boolean;
|
|
82
106
|
allowlistStrict?: boolean;
|
|
83
107
|
allowlistAdminKey?: string | null;
|
|
@@ -138,8 +162,12 @@ export declare class AgentChatServer {
|
|
|
138
162
|
verificationTimeoutMs: number;
|
|
139
163
|
pendingChallenges: Map<string, PendingChallenge>;
|
|
140
164
|
challengeTimeoutMs: number;
|
|
165
|
+
captchaConfig: CaptchaConfig;
|
|
166
|
+
openUntil: number;
|
|
167
|
+
pendingCaptchas: Map<string, PendingCaptcha>;
|
|
141
168
|
minProposalAgeMs: number;
|
|
142
169
|
redactor: Redactor;
|
|
170
|
+
genesisAgentId: string | null;
|
|
143
171
|
allowlist: Allowlist | null;
|
|
144
172
|
banlist: Banlist | null;
|
|
145
173
|
callbackQueue: CallbackQueue;
|
|
@@ -162,6 +190,12 @@ export declare class AgentChatServer {
|
|
|
162
190
|
* Get server health status
|
|
163
191
|
*/
|
|
164
192
|
getHealth(): HealthStatus;
|
|
193
|
+
/**
|
|
194
|
+
* Auto-join an agent to all public (non-invite-only) channels.
|
|
195
|
+
* Called after registration so the agent can immediately send messages
|
|
196
|
+
* without a separate JOIN handshake.
|
|
197
|
+
*/
|
|
198
|
+
_autoJoinPublicChannels(ws: ExtendedWebSocket): void;
|
|
165
199
|
_createChannel(name: string, inviteOnly?: boolean, verifiedOnly?: boolean): ChannelState;
|
|
166
200
|
/**
|
|
167
201
|
* Add a message to a channel's buffer (circular buffer)
|
package/dist/lib/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../lib/server.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAChD,OAAO,IAAyC,MAAM,MAAM,CAAC;AAC7D,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,EAIL,KAAK,EAGL,cAAc,EACd,UAAU,EACX,MAAM,YAAY,CAAC;AAQpB,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../lib/server.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/server.js
CHANGED
|
@@ -14,11 +14,13 @@ import { DisputeStore } from './disputes.js';
|
|
|
14
14
|
import { ReputationStore } from './reputation.js';
|
|
15
15
|
import { SkillsStore } from './skills-store.js';
|
|
16
16
|
import { EscrowHooks } from './escrow-hooks.js';
|
|
17
|
+
import geoip from 'geoip-lite';
|
|
17
18
|
import { Allowlist } from './allowlist.js';
|
|
18
19
|
import { Banlist } from './banlist.js';
|
|
19
20
|
import { Redactor } from './redactor.js';
|
|
20
21
|
import { CallbackQueue } from './callback-engine.js';
|
|
21
22
|
import { FloorControl } from './floor-control.js';
|
|
23
|
+
import { loadCaptchaConfig } from './captcha.js';
|
|
22
24
|
// Import extracted handlers
|
|
23
25
|
import { handleMsg, handleJoin, handleLeave, handleListChannels, handleListAgents, handleCreateChannel, handleInvite, handleFileChunk, } from './server/handlers/message.js';
|
|
24
26
|
import { handleProposal, handleAccept, handleReject, handleComplete, handleDispute, } from './server/handlers/proposal.js';
|
|
@@ -28,7 +30,9 @@ import { handleRegisterSkills, handleSearchSkills, } from './server/handlers/ski
|
|
|
28
30
|
import { handleSetPresence, } from './server/handlers/presence.js';
|
|
29
31
|
import { handleSetNick, } from './server/handlers/nick.js';
|
|
30
32
|
import { handleAdminApprove, handleAdminRevoke, handleAdminList, handleAdminMotd, } from './server/handlers/admin.js';
|
|
33
|
+
import { handleAdminVerify } from './server/handlers/admin.js';
|
|
31
34
|
import { handleAdminKick, handleAdminBan, handleAdminUnban, } from './server/handlers/ban.js';
|
|
35
|
+
import { handleCaptchaResponse, } from './server/handlers/captcha.js';
|
|
32
36
|
export class AgentChatServer {
|
|
33
37
|
port;
|
|
34
38
|
host;
|
|
@@ -75,10 +79,17 @@ export class AgentChatServer {
|
|
|
75
79
|
// Pending challenges (challenge-response auth)
|
|
76
80
|
pendingChallenges;
|
|
77
81
|
challengeTimeoutMs;
|
|
82
|
+
// Captcha
|
|
83
|
+
captchaConfig;
|
|
84
|
+
// Open window — new agents skip the 1-hour lurk until this timestamp
|
|
85
|
+
openUntil;
|
|
86
|
+
pendingCaptchas;
|
|
78
87
|
// Anti-sybil
|
|
79
88
|
minProposalAgeMs;
|
|
80
89
|
// Secret redactor (agentseenoevil)
|
|
81
90
|
redactor;
|
|
91
|
+
// Genesis agent ID — always verified
|
|
92
|
+
genesisAgentId;
|
|
82
93
|
// Allowlist
|
|
83
94
|
allowlist;
|
|
84
95
|
// Banlist
|
|
@@ -173,8 +184,13 @@ export class AgentChatServer {
|
|
|
173
184
|
this.challengeTimeoutMs = options.challengeTimeoutMs
|
|
174
185
|
|| parseInt(process.env.CHALLENGE_TIMEOUT_MS || '', 10)
|
|
175
186
|
|| 60000;
|
|
187
|
+
// Captcha
|
|
188
|
+
this.captchaConfig = loadCaptchaConfig();
|
|
189
|
+
this.pendingCaptchas = new Map();
|
|
176
190
|
// Anti-sybil
|
|
177
191
|
this.minProposalAgeMs = options.minProposalAgeMs ?? 60000;
|
|
192
|
+
// Genesis agent ID — hardcoded ID always granted verified:true
|
|
193
|
+
this.genesisAgentId = options.genesisAgentId || process.env.GENESIS_AGENT_ID || '8addfe276526c9f6';
|
|
178
194
|
// Allowlist
|
|
179
195
|
const allowlistEnabled = options.allowlistEnabled || process.env.ALLOWLIST_ENABLED === 'true';
|
|
180
196
|
if (allowlistEnabled) {
|
|
@@ -218,6 +234,7 @@ export class AgentChatServer {
|
|
|
218
234
|
this.maxConnectionsPerIp = options.maxConnectionsPerIp || parseInt(process.env.MAX_CONNECTIONS_PER_IP || '0');
|
|
219
235
|
this.connectionsByIp = new Map();
|
|
220
236
|
// WebSocket heartbeat
|
|
237
|
+
// Default heartbeat interval
|
|
221
238
|
this.heartbeatIntervalMs = options.heartbeatIntervalMs || 30000; // 30s
|
|
222
239
|
this.heartbeatTimeoutMs = options.heartbeatTimeoutMs || 10000; // 10s
|
|
223
240
|
this.heartbeatTimer = null;
|
|
@@ -255,6 +272,31 @@ export class AgentChatServer {
|
|
|
255
272
|
timestamp: new Date(now).toISOString()
|
|
256
273
|
};
|
|
257
274
|
}
|
|
275
|
+
/**
|
|
276
|
+
* Auto-join an agent to all public (non-invite-only) channels.
|
|
277
|
+
* Called after registration so the agent can immediately send messages
|
|
278
|
+
* without a separate JOIN handshake.
|
|
279
|
+
*/
|
|
280
|
+
_autoJoinPublicChannels(ws) {
|
|
281
|
+
const agent = this.agents.get(ws);
|
|
282
|
+
if (!agent)
|
|
283
|
+
return;
|
|
284
|
+
for (const [name, channel] of this.channels) {
|
|
285
|
+
if (channel.inviteOnly)
|
|
286
|
+
continue;
|
|
287
|
+
if (channel.verifiedOnly && !agent.verified)
|
|
288
|
+
continue;
|
|
289
|
+
channel.agents.add(ws);
|
|
290
|
+
agent.channels.add(name);
|
|
291
|
+
// Broadcast join to existing members
|
|
292
|
+
this._broadcast(name, createMessage(ServerMessageType.AGENT_JOINED, {
|
|
293
|
+
channel: name,
|
|
294
|
+
agent: `@${agent.id}`,
|
|
295
|
+
name: agent.name,
|
|
296
|
+
verified: !!agent.verified
|
|
297
|
+
}), ws);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
258
300
|
_createChannel(name, inviteOnly = false, verifiedOnly = false) {
|
|
259
301
|
if (!this.channels.has(name)) {
|
|
260
302
|
this.channels.set(name, {
|
|
@@ -328,16 +370,34 @@ export class AgentChatServer {
|
|
|
328
370
|
return agent.lurk === true;
|
|
329
371
|
}
|
|
330
372
|
_log(event, data = {}) {
|
|
373
|
+
// Default log level can be overridden by caller via data.level
|
|
374
|
+
const level = (data && data.level) || 'info';
|
|
331
375
|
const entry = {
|
|
332
376
|
ts: new Date().toISOString(),
|
|
377
|
+
level,
|
|
333
378
|
event,
|
|
334
379
|
...data
|
|
335
380
|
};
|
|
336
|
-
|
|
381
|
+
// Ensure stack traces (if present) are strings so JSON.stringify doesn't drop them
|
|
382
|
+
if (entry.error instanceof Error) {
|
|
383
|
+
entry.error = { message: entry.error.message, stack: entry.error.stack };
|
|
384
|
+
}
|
|
385
|
+
try {
|
|
386
|
+
console.error(JSON.stringify(entry));
|
|
387
|
+
}
|
|
388
|
+
catch (err) {
|
|
389
|
+
// Fallback if circular values sneaked in
|
|
390
|
+
console.error(event, entry, String(err));
|
|
391
|
+
}
|
|
337
392
|
}
|
|
338
393
|
_send(ws, msg) {
|
|
339
394
|
if (ws.readyState === 1) { // OPEN
|
|
340
|
-
|
|
395
|
+
try {
|
|
396
|
+
ws.send(serialize(msg));
|
|
397
|
+
}
|
|
398
|
+
catch (err) {
|
|
399
|
+
this._log('send_error', { error: err instanceof Error ? { message: err.message, stack: err.stack } : String(err), conn_id: ws._connId });
|
|
400
|
+
}
|
|
341
401
|
}
|
|
342
402
|
}
|
|
343
403
|
_broadcast(channel, msg, excludeWs = null) {
|
|
@@ -364,6 +424,24 @@ export class AgentChatServer {
|
|
|
364
424
|
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
365
425
|
res.end(JSON.stringify(health));
|
|
366
426
|
}
|
|
427
|
+
else if (req.method === 'GET' && req.url === '/api/connections') {
|
|
428
|
+
// Get current connections with geo data
|
|
429
|
+
const connections = Array.from(this.agentById.entries()).map(([agentId, ws]) => {
|
|
430
|
+
const ews = ws;
|
|
431
|
+
return {
|
|
432
|
+
agent_id: agentId,
|
|
433
|
+
ip: ews._realIp,
|
|
434
|
+
country: ews._geoCountry,
|
|
435
|
+
city: ews._geoCity,
|
|
436
|
+
lat: ews._geoLat,
|
|
437
|
+
lon: ews._geoLon,
|
|
438
|
+
connected_at: ews._connectedAt,
|
|
439
|
+
user_agent: ews._userAgent
|
|
440
|
+
};
|
|
441
|
+
});
|
|
442
|
+
res.writeHead(200, { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*' });
|
|
443
|
+
res.end(JSON.stringify({ connections, count: connections.length }));
|
|
444
|
+
}
|
|
367
445
|
else {
|
|
368
446
|
res.writeHead(404);
|
|
369
447
|
res.end('Not Found');
|
|
@@ -420,22 +498,44 @@ export class AgentChatServer {
|
|
|
420
498
|
}
|
|
421
499
|
// Store connection metadata on ws for later logging
|
|
422
500
|
ws._connectedAt = Date.now();
|
|
501
|
+
// Short connection identifier for correlation with logs
|
|
502
|
+
ws._connId = `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
|
|
423
503
|
ws._realIp = realIp;
|
|
424
504
|
ws._userAgent = userAgent;
|
|
425
505
|
ws._isAlive = true;
|
|
506
|
+
// GeoIP lookup
|
|
507
|
+
if (realIp) {
|
|
508
|
+
const geo = geoip.lookup(realIp);
|
|
509
|
+
if (geo) {
|
|
510
|
+
ws._geoCountry = geo.country;
|
|
511
|
+
ws._geoCity = geo.city;
|
|
512
|
+
ws._geoLat = geo.ll?.[0];
|
|
513
|
+
ws._geoLon = geo.ll?.[1];
|
|
514
|
+
}
|
|
515
|
+
}
|
|
426
516
|
// WS-level pong handler for heartbeat
|
|
427
517
|
ws.on('pong', () => {
|
|
428
518
|
ws._isAlive = true;
|
|
519
|
+
ws._lastPong = Date.now();
|
|
429
520
|
});
|
|
430
521
|
this._log('connection', {
|
|
431
522
|
ip: realIp,
|
|
432
523
|
proxy_ip: req.socket.remoteAddress,
|
|
433
|
-
user_agent: userAgent
|
|
524
|
+
user_agent: userAgent,
|
|
525
|
+
conn_id: ws._connId,
|
|
526
|
+
country: ws._geoCountry,
|
|
527
|
+
city: ws._geoCity
|
|
434
528
|
});
|
|
435
529
|
ws.on('message', (data) => {
|
|
530
|
+
// Log raw receive (size only) for correlation — avoid logging payloads
|
|
531
|
+
try {
|
|
532
|
+
this._log('ws_message_recv', { conn_id: ws._connId, size: data.length, ip: ws._realIp });
|
|
533
|
+
}
|
|
534
|
+
catch { }
|
|
436
535
|
this._handleMessage(ws, data.toString());
|
|
437
536
|
});
|
|
438
|
-
ws.on('close', () => {
|
|
537
|
+
ws.on('close', (code, reason) => {
|
|
538
|
+
const reasonStr = reason ? reason.toString() : undefined;
|
|
439
539
|
// Decrement per-IP connection count
|
|
440
540
|
if (ws._realIp && this.maxConnectionsPerIp > 0) {
|
|
441
541
|
const current = this.connectionsByIp.get(ws._realIp) || 0;
|
|
@@ -457,28 +557,44 @@ export class AgentChatServer {
|
|
|
457
557
|
});
|
|
458
558
|
}
|
|
459
559
|
}
|
|
560
|
+
// Clean up any pending captchas for this ws
|
|
561
|
+
for (const [captchaId, captcha] of this.pendingCaptchas) {
|
|
562
|
+
if (captcha.ws === ws) {
|
|
563
|
+
this.pendingCaptchas.delete(captchaId);
|
|
564
|
+
this._log('captcha_abandoned', {
|
|
565
|
+
captchaId,
|
|
566
|
+
ip: ws._realIp,
|
|
567
|
+
reason: 'websocket_closed'
|
|
568
|
+
});
|
|
569
|
+
}
|
|
570
|
+
}
|
|
460
571
|
// Log if connection closed without ever identifying (drive-by)
|
|
461
572
|
if (!this.agents.has(ws)) {
|
|
462
573
|
const duration = ws._connectedAt ? Math.round((Date.now() - ws._connectedAt) / 1000) : 0;
|
|
463
574
|
this._log('connection_closed_unidentified', {
|
|
464
575
|
ip: ws._realIp,
|
|
465
576
|
duration_sec: duration,
|
|
466
|
-
user_agent: ws._userAgent
|
|
577
|
+
user_agent: ws._userAgent,
|
|
578
|
+
conn_id: ws._connId,
|
|
579
|
+
close_code: code,
|
|
580
|
+
close_reason: reasonStr
|
|
467
581
|
});
|
|
468
582
|
}
|
|
469
583
|
this._handleDisconnect(ws);
|
|
470
584
|
});
|
|
471
585
|
ws.on('error', (err) => {
|
|
472
|
-
this._log('ws_error', { error: err.message });
|
|
473
|
-
this
|
|
586
|
+
this._log('ws_error', { error: err instanceof Error ? { message: err.message, stack: err.stack } : String(err), conn_id: ws._connId, ip: ws._realIp });
|
|
587
|
+
// Attempt graceful shutdown of this socket
|
|
474
588
|
try {
|
|
475
589
|
ws.close(1006, 'WebSocket error');
|
|
476
590
|
}
|
|
477
591
|
catch { }
|
|
592
|
+
// Defer to disconnect handler for cleanup
|
|
593
|
+
this._handleDisconnect(ws);
|
|
478
594
|
});
|
|
479
595
|
});
|
|
480
596
|
this.wss.on('error', (err) => {
|
|
481
|
-
this._log('server_error', { error: err.message });
|
|
597
|
+
this._log('server_error', { error: err instanceof Error ? { message: err.message, stack: err.stack } : String(err) });
|
|
482
598
|
});
|
|
483
599
|
// Start idle channel checker
|
|
484
600
|
this.idleCheckInterval = setInterval(() => {
|
|
@@ -488,18 +604,32 @@ export class AgentChatServer {
|
|
|
488
604
|
this.heartbeatTimer = setInterval(() => {
|
|
489
605
|
if (!this.wss)
|
|
490
606
|
return;
|
|
607
|
+
const now = Date.now();
|
|
491
608
|
this.wss.clients.forEach((ws) => {
|
|
492
609
|
const ews = ws;
|
|
493
|
-
|
|
610
|
+
// If we haven't seen a pong in 2x heartbeat interval, consider connection stale
|
|
611
|
+
const lastPong = ews._lastPong || ews._connectedAt || 0;
|
|
612
|
+
if (now - lastPong > (this.heartbeatIntervalMs * 2 + this.heartbeatTimeoutMs)) {
|
|
494
613
|
this._log('heartbeat_timeout', {
|
|
495
614
|
ip: ews._realIp,
|
|
496
615
|
agent: this.agents.get(ews)?.id,
|
|
616
|
+
conn_id: ews._connId,
|
|
617
|
+
last_pong_ms: lastPong ? now - lastPong : null
|
|
497
618
|
});
|
|
498
619
|
this._handleDisconnect(ews);
|
|
499
|
-
|
|
620
|
+
try {
|
|
621
|
+
return ews.terminate();
|
|
622
|
+
}
|
|
623
|
+
catch { }
|
|
624
|
+
}
|
|
625
|
+
// Send a ping and record send time for correlation
|
|
626
|
+
try {
|
|
627
|
+
ews._isAlive = false;
|
|
628
|
+
ews.ping();
|
|
629
|
+
}
|
|
630
|
+
catch (err) {
|
|
631
|
+
this._log('heartbeat_ping_error', { error: err instanceof Error ? { message: err.message, stack: err.stack } : String(err), conn_id: ews._connId, ip: ews._realIp });
|
|
500
632
|
}
|
|
501
|
-
ews._isAlive = false;
|
|
502
|
-
ews.ping();
|
|
503
633
|
});
|
|
504
634
|
}, this.heartbeatIntervalMs);
|
|
505
635
|
return this;
|
|
@@ -603,7 +733,9 @@ export class AgentChatServer {
|
|
|
603
733
|
}
|
|
604
734
|
const result = validateClientMessage(data);
|
|
605
735
|
if (!result.valid) {
|
|
606
|
-
|
|
736
|
+
const errorStr = result.error;
|
|
737
|
+
this._log('invalid_message', { conn_id: ws._connId, ip: ws._realIp, error: errorStr, payload_preview: data.slice(0, 200) });
|
|
738
|
+
this._send(ws, createError(ErrorCode.INVALID_MSG, errorStr));
|
|
607
739
|
return;
|
|
608
740
|
}
|
|
609
741
|
const msg = result.msg;
|
|
@@ -698,6 +830,10 @@ export class AgentChatServer {
|
|
|
698
830
|
case ClientMessageType.VERIFY_IDENTITY:
|
|
699
831
|
handleVerifyIdentity(this, ws, msg);
|
|
700
832
|
break;
|
|
833
|
+
// Captcha response
|
|
834
|
+
case ClientMessageType.CAPTCHA_RESPONSE:
|
|
835
|
+
handleCaptchaResponse(this, ws, msg);
|
|
836
|
+
break;
|
|
701
837
|
// Nick
|
|
702
838
|
case ClientMessageType.SET_NICK:
|
|
703
839
|
handleSetNick(this, ws, msg);
|
|
@@ -725,6 +861,9 @@ export class AgentChatServer {
|
|
|
725
861
|
case ClientMessageType.ADMIN_MOTD:
|
|
726
862
|
handleAdminMotd(this, ws, msg);
|
|
727
863
|
break;
|
|
864
|
+
case ClientMessageType.ADMIN_VERIFY:
|
|
865
|
+
handleAdminVerify(this, ws, msg);
|
|
866
|
+
break;
|
|
728
867
|
// Floor control — RESPONDING_TO
|
|
729
868
|
case ClientMessageType.RESPONDING_TO: {
|
|
730
869
|
const rtAgent = this.agents.get(ws);
|