@tjamescouch/agentchat 0.9.0 → 0.10.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/lib/server.js +66 -7
- package/package.json +1 -1
package/lib/server.js
CHANGED
|
@@ -23,6 +23,7 @@ import {
|
|
|
23
23
|
isProposalMessage
|
|
24
24
|
} from './protocol.js';
|
|
25
25
|
import { ProposalStore, formatProposal, formatProposalResponse } from './proposals.js';
|
|
26
|
+
import { ReputationStore } from './reputation.js';
|
|
26
27
|
|
|
27
28
|
export class AgentChatServer {
|
|
28
29
|
constructor(options = {}) {
|
|
@@ -75,6 +76,9 @@ export class AgentChatServer {
|
|
|
75
76
|
// Skills registry: agentId -> { skills: [], registered_at, sig }
|
|
76
77
|
this.skillsRegistry = new Map();
|
|
77
78
|
|
|
79
|
+
// Reputation store for ELO ratings
|
|
80
|
+
this.reputationStore = new ReputationStore();
|
|
81
|
+
|
|
78
82
|
this.wss = null;
|
|
79
83
|
this.httpServer = null; // For TLS mode
|
|
80
84
|
}
|
|
@@ -780,7 +784,7 @@ export class AgentChatServer {
|
|
|
780
784
|
this._send(ws, outMsg);
|
|
781
785
|
}
|
|
782
786
|
|
|
783
|
-
_handleComplete(ws, msg) {
|
|
787
|
+
async _handleComplete(ws, msg) {
|
|
784
788
|
const agent = this.agents.get(ws);
|
|
785
789
|
if (!agent) {
|
|
786
790
|
this._send(ws, createError(ErrorCode.AUTH_REQUIRED, 'Must IDENTIFY first'));
|
|
@@ -807,9 +811,27 @@ export class AgentChatServer {
|
|
|
807
811
|
const proposal = result.proposal;
|
|
808
812
|
this._log('complete', { id: proposal.id, by: agent.id });
|
|
809
813
|
|
|
814
|
+
// Update reputation ratings
|
|
815
|
+
let ratingChanges = null;
|
|
816
|
+
try {
|
|
817
|
+
ratingChanges = await this.reputationStore.processCompletion({
|
|
818
|
+
type: 'COMPLETE',
|
|
819
|
+
from: proposal.from,
|
|
820
|
+
to: proposal.to,
|
|
821
|
+
amount: proposal.amount
|
|
822
|
+
});
|
|
823
|
+
this._log('reputation_updated', {
|
|
824
|
+
proposal_id: proposal.id,
|
|
825
|
+
changes: ratingChanges
|
|
826
|
+
});
|
|
827
|
+
} catch (err) {
|
|
828
|
+
this._log('reputation_error', { error: err.message });
|
|
829
|
+
}
|
|
830
|
+
|
|
810
831
|
// Notify both parties
|
|
811
832
|
const outMsg = createMessage(ServerMessageType.COMPLETE, {
|
|
812
|
-
...formatProposalResponse(proposal, 'complete')
|
|
833
|
+
...formatProposalResponse(proposal, 'complete'),
|
|
834
|
+
rating_changes: ratingChanges
|
|
813
835
|
});
|
|
814
836
|
|
|
815
837
|
// Notify the other party
|
|
@@ -823,7 +845,7 @@ export class AgentChatServer {
|
|
|
823
845
|
this._send(ws, outMsg);
|
|
824
846
|
}
|
|
825
847
|
|
|
826
|
-
_handleDispute(ws, msg) {
|
|
848
|
+
async _handleDispute(ws, msg) {
|
|
827
849
|
const agent = this.agents.get(ws);
|
|
828
850
|
if (!agent) {
|
|
829
851
|
this._send(ws, createError(ErrorCode.AUTH_REQUIRED, 'Must IDENTIFY first'));
|
|
@@ -850,9 +872,28 @@ export class AgentChatServer {
|
|
|
850
872
|
const proposal = result.proposal;
|
|
851
873
|
this._log('dispute', { id: proposal.id, by: agent.id, reason: msg.reason });
|
|
852
874
|
|
|
875
|
+
// Update reputation ratings
|
|
876
|
+
let ratingChanges = null;
|
|
877
|
+
try {
|
|
878
|
+
ratingChanges = await this.reputationStore.processDispute({
|
|
879
|
+
type: 'DISPUTE',
|
|
880
|
+
from: proposal.from,
|
|
881
|
+
to: proposal.to,
|
|
882
|
+
amount: proposal.amount,
|
|
883
|
+
disputed_by: `@${agent.id}`
|
|
884
|
+
});
|
|
885
|
+
this._log('reputation_updated', {
|
|
886
|
+
proposal_id: proposal.id,
|
|
887
|
+
changes: ratingChanges
|
|
888
|
+
});
|
|
889
|
+
} catch (err) {
|
|
890
|
+
this._log('reputation_error', { error: err.message });
|
|
891
|
+
}
|
|
892
|
+
|
|
853
893
|
// Notify both parties
|
|
854
894
|
const outMsg = createMessage(ServerMessageType.DISPUTE, {
|
|
855
|
-
...formatProposalResponse(proposal, 'dispute')
|
|
895
|
+
...formatProposalResponse(proposal, 'dispute'),
|
|
896
|
+
rating_changes: ratingChanges
|
|
856
897
|
});
|
|
857
898
|
|
|
858
899
|
// Notify the other party
|
|
@@ -907,7 +948,7 @@ export class AgentChatServer {
|
|
|
907
948
|
}
|
|
908
949
|
}
|
|
909
950
|
|
|
910
|
-
_handleSearchSkills(ws, msg) {
|
|
951
|
+
async _handleSearchSkills(ws, msg) {
|
|
911
952
|
const agent = this.agents.get(ws);
|
|
912
953
|
if (!agent) {
|
|
913
954
|
this._send(ws, createError(ErrorCode.AUTH_REQUIRED, 'Must IDENTIFY first'));
|
|
@@ -955,8 +996,26 @@ export class AgentChatServer {
|
|
|
955
996
|
}
|
|
956
997
|
}
|
|
957
998
|
|
|
958
|
-
//
|
|
959
|
-
results.
|
|
999
|
+
// Enrich results with reputation data
|
|
1000
|
+
const uniqueAgentIds = [...new Set(results.map(r => r.agent_id))];
|
|
1001
|
+
const ratingCache = new Map();
|
|
1002
|
+
for (const agentId of uniqueAgentIds) {
|
|
1003
|
+
const ratingInfo = await this.reputationStore.getRating(agentId);
|
|
1004
|
+
ratingCache.set(agentId, ratingInfo);
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
// Add rating info to each result
|
|
1008
|
+
for (const result of results) {
|
|
1009
|
+
const ratingInfo = ratingCache.get(result.agent_id);
|
|
1010
|
+
result.rating = ratingInfo.rating;
|
|
1011
|
+
result.transactions = ratingInfo.transactions;
|
|
1012
|
+
}
|
|
1013
|
+
|
|
1014
|
+
// Sort by rating (highest first), then by registration time
|
|
1015
|
+
results.sort((a, b) => {
|
|
1016
|
+
if (b.rating !== a.rating) return b.rating - a.rating;
|
|
1017
|
+
return b.registered_at - a.registered_at;
|
|
1018
|
+
});
|
|
960
1019
|
|
|
961
1020
|
// Limit results
|
|
962
1021
|
const limit = query.limit || 50;
|