@coolclaw/coolclaw 1.0.0 → 1.0.1
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.
|
@@ -209,13 +209,13 @@ function renderPlayerInfo(list, selfSeat) {
|
|
|
209
209
|
if (list.length === 0) return "\uFF08\u65E0\u5EA7\u4F4D\u4FE1\u606F\uFF09";
|
|
210
210
|
return list.map((p) => {
|
|
211
211
|
const seat = asNumberOrNull(p.seat);
|
|
212
|
-
const
|
|
212
|
+
const playerStatus = p.alive === true ? "\u5B58\u6D3B" : p.alive === false ? "\u5DF2\u6B7B\u4EA1" : "\u53C2\u8D5B";
|
|
213
213
|
if (seat != null && selfSeat != null && seat === selfSeat) {
|
|
214
214
|
const name = asString(p.name, "\u672A\u77E5");
|
|
215
215
|
const voice = asString(p.voiceDesc, "");
|
|
216
|
-
return `\u5EA7\u4F4D${seat}\uFF08\u4F60\u81EA\u5DF1\uFF0C${name}${voice ? `\uFF0C${voice}` : ""}\uFF0C${
|
|
216
|
+
return `\u5EA7\u4F4D${seat}\uFF08\u4F60\u81EA\u5DF1\uFF0C${name}${voice ? `\uFF0C${voice}` : ""}\uFF0C${playerStatus}\uFF09`;
|
|
217
217
|
}
|
|
218
|
-
return `\u5EA7\u4F4D${seat ?? "?"}\uFF08${
|
|
218
|
+
return `\u5EA7\u4F4D${seat ?? "?"}\uFF08${playerStatus}\uFF09`;
|
|
219
219
|
}).join("\uFF1B");
|
|
220
220
|
}
|
|
221
221
|
function stripAudioSuffix(line) {
|
|
@@ -228,20 +228,42 @@ function renderHistory(history) {
|
|
|
228
228
|
function renderAliveSeats(seats) {
|
|
229
229
|
return seats.length === 0 ? "\uFF08\u65E0\uFF09" : `[${seats.join(", ")}]`;
|
|
230
230
|
}
|
|
231
|
+
function asMvpCandidates(v) {
|
|
232
|
+
if (!Array.isArray(v)) return [];
|
|
233
|
+
return v.flatMap((item) => {
|
|
234
|
+
if (typeof item === "number" && Number.isFinite(item)) {
|
|
235
|
+
return [{ agentId: item, seatNumber: null }];
|
|
236
|
+
}
|
|
237
|
+
const record = asRecord(item);
|
|
238
|
+
const agentId = asNumberOrNull(record.agentId) ?? asNumberOrNull(record.targetAgentId);
|
|
239
|
+
if (agentId == null) return [];
|
|
240
|
+
const seatNumber = asNumberOrNull(record.seatNumber) ?? asNumberOrNull(record.seat);
|
|
241
|
+
return [{ agentId, seatNumber }];
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
function renderMvpCandidateList(candidates, selfAgentId) {
|
|
245
|
+
if (candidates.length === 0) return "\uFF08\u5019\u9009\u4FE1\u606F\u7F3A\u5931\uFF1B\u7B49\u5F85\u5E73\u53F0\u8D85\u65F6\u515C\u5E95\uFF09";
|
|
246
|
+
return candidates.map((candidate) => {
|
|
247
|
+
const seat = candidate.seatNumber == null ? "?" : candidate.seatNumber;
|
|
248
|
+
const selfMark = selfAgentId != null && candidate.agentId === selfAgentId ? "\uFF08\u4F60\u81EA\u5DF1\uFF0C\u4E0D\u80FD\u6295\u7ED9\u81EA\u5DF1\uFF09" : "";
|
|
249
|
+
return `- \u5EA7\u4F4D${seat} / Agent ${candidate.agentId}${selfMark}`;
|
|
250
|
+
}).join("\n");
|
|
251
|
+
}
|
|
231
252
|
function renderHeader(eventType, outer, payload) {
|
|
232
253
|
const round = asNumberOrNull(outer.round) ?? 1;
|
|
233
254
|
const selfSeat = asNumberOrNull(payload.selfSeat);
|
|
234
255
|
const selfRole = asString(payload.selfRole, "\u672A\u77E5");
|
|
235
256
|
const selfName = asString(payload.selfAgentName, "");
|
|
236
|
-
const phase = eventType.startsWith("DAY_") || eventType === "LAST_WORD_TURN" || eventType === "HUNTER_SKILL_TURN" ? "\u767D\u5929" : "\u591C\u665A";
|
|
257
|
+
const phase = eventType === "MVP_VOTE_REQUEST" ? "\u8D5B\u540E" : eventType.startsWith("DAY_") || eventType === "LAST_WORD_TURN" || eventType === "HUNTER_SKILL_TURN" ? "\u767D\u5929" : "\u591C\u665A";
|
|
237
258
|
const aliveSeats = asNumberArray(payload.aliveSeats);
|
|
259
|
+
const seatsLabel = eventType === "MVP_VOTE_REQUEST" ? "MVP \u5019\u9009\u5EA7\u4F4D" : "\u5F53\u524D\u5B58\u6D3B\u5EA7\u4F4D";
|
|
238
260
|
const playerInfo = renderPlayerInfo(asRecordArray(payload.playerInfoList), selfSeat);
|
|
239
261
|
const history = renderHistory(asStringArray(payload.scopedHistory));
|
|
240
262
|
return [
|
|
241
263
|
`[\u6E38\u620F] \u72FC\u4EBA\u6740 \xB7 \u7B2C ${round} \u8F6E \xB7 ${phase} \xB7 ${describeEventType(eventType)}`,
|
|
242
264
|
``,
|
|
243
265
|
`\u4F60\u662F\u5EA7\u4F4D ${selfSeat ?? "?"} \u7684 ${selfRole}${selfName ? `\uFF08${selfName}\uFF09` : ""}\u3002`,
|
|
244
|
-
|
|
266
|
+
`${seatsLabel}\uFF1A${renderAliveSeats(aliveSeats)}\u3002`,
|
|
245
267
|
`\u5168\u4F53\u73A9\u5BB6\uFF1A${playerInfo}`,
|
|
246
268
|
``,
|
|
247
269
|
`\u3010\u8FD1\u671F\u5386\u53F2\uFF08\u4EC5\u4F60\u53EF\u89C1\uFF09\u3011`,
|
|
@@ -265,6 +287,8 @@ function describeEventType(eventType) {
|
|
|
265
287
|
return "\u767D\u5929\u6295\u7968";
|
|
266
288
|
case "HUNTER_SKILL_TURN":
|
|
267
289
|
return "\u730E\u4EBA\u6280\u80FD";
|
|
290
|
+
case "MVP_VOTE_REQUEST":
|
|
291
|
+
return "MVP \u6295\u7968";
|
|
268
292
|
default:
|
|
269
293
|
return eventType;
|
|
270
294
|
}
|
|
@@ -285,6 +309,8 @@ function renderTask(eventType, payload) {
|
|
|
285
309
|
return renderDayVoteTurn(payload);
|
|
286
310
|
case "HUNTER_SKILL_TURN":
|
|
287
311
|
return renderHunterTurn(payload);
|
|
312
|
+
case "MVP_VOTE_REQUEST":
|
|
313
|
+
return renderMvpVoteRequest(payload);
|
|
288
314
|
default:
|
|
289
315
|
return renderUnknownTurn(eventType);
|
|
290
316
|
}
|
|
@@ -419,6 +445,23 @@ function renderHunterTurn(payload) {
|
|
|
419
445
|
`<ACTION>{"actionType":"HUNTER_PASS","actionData":{}}</ACTION>`
|
|
420
446
|
].join("\n");
|
|
421
447
|
}
|
|
448
|
+
function renderMvpVoteRequest(payload) {
|
|
449
|
+
const candidates = asMvpCandidates(payload.candidates);
|
|
450
|
+
const selfAgentId = asNumberOrNull(payload.selfAgentId);
|
|
451
|
+
const round = asNumberOrNull(payload.round) ?? 1;
|
|
452
|
+
const deadlineSeconds = asNumberOrNull(payload.deadlineSeconds);
|
|
453
|
+
return [
|
|
454
|
+
`\u3010\u4EFB\u52A1\u3011\u8D5B\u540E MVP \u6295\u7968\uFF08\u7B2C ${round} \u8F6E\uFF09`,
|
|
455
|
+
deadlineSeconds != null ? `\u8BF7\u5728 ${deadlineSeconds} \u79D2\u5185\u4ECE\u5019\u9009\u5BF9\u8C61\u91CC\u9009\u51FA\u4F60\u8BA4\u4E3A\u672C\u5C40\u8D21\u732E\u6700\u5927\u7684 Agent\u3002` : `\u8BF7\u4ECE\u5019\u9009\u5BF9\u8C61\u91CC\u9009\u51FA\u4F60\u8BA4\u4E3A\u672C\u5C40\u8D21\u732E\u6700\u5927\u7684 Agent\u3002`,
|
|
456
|
+
`\u5019\u9009\u5BF9\u8C61\uFF08targetAgentId \u5FC5\u987B\u4ECE\u8FD9\u91CC\u9009\uFF0C\u4E0D\u80FD\u6295\u7ED9\u81EA\u5DF1\uFF09\uFF1A`,
|
|
457
|
+
renderMvpCandidateList(candidates, selfAgentId),
|
|
458
|
+
``,
|
|
459
|
+
`\u8BF7\u7EFC\u5408\u53D1\u8A00\u3001\u6295\u7968\u3001\u5173\u952E\u884C\u52A8\u548C\u80DC\u8D1F\u8D21\u732E\uFF0C\u7B80\u77ED\u8BF4\u660E\u7406\u7531\uFF0C\u7136\u540E\u5728\u56DE\u590D\u6700\u540E\u4E25\u683C\u6309\u4EE5\u4E0B\u683C\u5F0F\u58F0\u660E\u52A8\u4F5C\uFF1A`,
|
|
460
|
+
`<ACTION>`,
|
|
461
|
+
`{"actionType":"MVP_VOTE","actionData":{"targetAgentId":<number>,"round":${round},"reason":"<\u7B80\u8FF0>"}}`,
|
|
462
|
+
`</ACTION>`
|
|
463
|
+
].join("\n");
|
|
464
|
+
}
|
|
422
465
|
function renderUnknownTurn(eventType) {
|
|
423
466
|
return [
|
|
424
467
|
`\u3010\u63D0\u793A\u3011\u672A\u8BC6\u522B\u7684\u6E38\u620F\u4E8B\u4EF6\u7C7B\u578B\uFF1A${eventType}`,
|
|
@@ -427,7 +470,8 @@ function renderUnknownTurn(eventType) {
|
|
|
427
470
|
}
|
|
428
471
|
function buildGameEventPrompt(eventType, eventData) {
|
|
429
472
|
const outer = asRecord(eventData);
|
|
430
|
-
const
|
|
473
|
+
const nestedPayload = asRecord(outer.payload);
|
|
474
|
+
const payload = Object.keys(nestedPayload).length > 0 ? nestedPayload : outer;
|
|
431
475
|
const header = renderHeader(eventType, outer, payload);
|
|
432
476
|
const task = renderTask(eventType, payload);
|
|
433
477
|
const footer = `
|
|
@@ -847,16 +891,38 @@ function parseAgentAction(text) {
|
|
|
847
891
|
function asNumberArray2(v) {
|
|
848
892
|
return Array.isArray(v) ? v.filter((x) => typeof x === "number") : [];
|
|
849
893
|
}
|
|
894
|
+
function asNumberOrNull2(v) {
|
|
895
|
+
return typeof v === "number" && Number.isFinite(v) ? v : null;
|
|
896
|
+
}
|
|
850
897
|
function asRecord2(v) {
|
|
851
898
|
return typeof v === "object" && v !== null ? v : {};
|
|
852
899
|
}
|
|
900
|
+
function hasKeys(record) {
|
|
901
|
+
return Object.keys(record).length > 0;
|
|
902
|
+
}
|
|
903
|
+
function candidateAgentIds(v) {
|
|
904
|
+
if (!Array.isArray(v)) return [];
|
|
905
|
+
return v.flatMap((item) => {
|
|
906
|
+
if (typeof item === "number" && Number.isFinite(item)) return [item];
|
|
907
|
+
const record = asRecord2(item);
|
|
908
|
+
const agentId = asNumberOrNull2(record.agentId) ?? asNumberOrNull2(record.targetAgentId);
|
|
909
|
+
return agentId == null ? [] : [agentId];
|
|
910
|
+
});
|
|
911
|
+
}
|
|
853
912
|
function pickRandomAlive(aliveSeats, excludeSeat) {
|
|
854
913
|
const candidates = excludeSeat != null ? aliveSeats.filter((s) => s !== excludeSeat) : aliveSeats;
|
|
855
914
|
if (candidates.length === 0) return null;
|
|
856
915
|
return candidates[Math.floor(Math.random() * candidates.length)];
|
|
857
916
|
}
|
|
917
|
+
function pickRandomAgent(candidates, excludeAgentId) {
|
|
918
|
+
const eligible = excludeAgentId == null ? candidates : candidates.filter((candidate) => candidate !== excludeAgentId);
|
|
919
|
+
if (eligible.length === 0) return candidates[0] ?? null;
|
|
920
|
+
return eligible[Math.floor(Math.random() * eligible.length)];
|
|
921
|
+
}
|
|
858
922
|
function fallbackActionFor(eventType, eventData) {
|
|
859
|
-
const
|
|
923
|
+
const outer = asRecord2(eventData);
|
|
924
|
+
const nestedPayload = asRecord2(outer.payload);
|
|
925
|
+
const payload = hasKeys(nestedPayload) ? nestedPayload : outer;
|
|
860
926
|
const aliveSeats = asNumberArray2(payload.aliveSeats);
|
|
861
927
|
const selfSeat = typeof payload.selfSeat === "number" ? payload.selfSeat : void 0;
|
|
862
928
|
switch (eventType) {
|
|
@@ -901,6 +967,22 @@ function fallbackActionFor(eventType, eventData) {
|
|
|
901
967
|
};
|
|
902
968
|
case "HUNTER_SKILL_TURN":
|
|
903
969
|
return { actionType: "HUNTER_PASS", actionData: {} };
|
|
970
|
+
case "MVP_VOTE_REQUEST": {
|
|
971
|
+
const selfAgentId = asNumberOrNull2(payload.selfAgentId);
|
|
972
|
+
const candidates = candidateAgentIds(payload.candidates);
|
|
973
|
+
const targetAgentId = pickRandomAgent(candidates, selfAgentId);
|
|
974
|
+
if (targetAgentId == null) {
|
|
975
|
+
return { actionType: "UNKNOWN", actionData: {} };
|
|
976
|
+
}
|
|
977
|
+
return {
|
|
978
|
+
actionType: "MVP_VOTE",
|
|
979
|
+
actionData: {
|
|
980
|
+
targetAgentId,
|
|
981
|
+
round: asNumberOrNull2(payload.round) ?? asNumberOrNull2(outer.round) ?? 1,
|
|
982
|
+
reason: "\uFF08\u6258\u7BA1\uFF1ALLM \u672A\u7ED9\u51FA\u5408\u6CD5 MVP \u6295\u7968\uFF09"
|
|
983
|
+
}
|
|
984
|
+
};
|
|
985
|
+
}
|
|
904
986
|
default:
|
|
905
987
|
return { actionType: "UNKNOWN", actionData: {} };
|
|
906
988
|
}
|
|
@@ -912,6 +994,7 @@ var CoolclawWsClient = class {
|
|
|
912
994
|
constructor(options) {
|
|
913
995
|
this.options = options;
|
|
914
996
|
}
|
|
997
|
+
options;
|
|
915
998
|
socket;
|
|
916
999
|
heartbeatTimer;
|
|
917
1000
|
reconnectTimer;
|
package/dist/cli-metadata.js
CHANGED
package/dist/index.js
CHANGED
package/dist/setup-entry.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@coolclaw/coolclaw",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "OpenClaw native channel plugin for Riddle/CoolClaw chat.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -41,16 +41,16 @@
|
|
|
41
41
|
"lint": "tsc --noEmit"
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"ws": "
|
|
45
|
-
"zod": "
|
|
44
|
+
"ws": "^8.20.1",
|
|
45
|
+
"zod": "^4.4.3"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
|
-
"@types/node": "
|
|
49
|
-
"@types/ws": "
|
|
48
|
+
"@types/node": "^25.8.0",
|
|
49
|
+
"@types/ws": "^8.18.1",
|
|
50
50
|
"openclaw": "^2026.4.27",
|
|
51
|
-
"tsup": "
|
|
52
|
-
"typescript": "
|
|
53
|
-
"vitest": "
|
|
51
|
+
"tsup": "^8.5.1",
|
|
52
|
+
"typescript": "^6.0.3",
|
|
53
|
+
"vitest": "^4.1.6"
|
|
54
54
|
},
|
|
55
55
|
"peerDependencies": {
|
|
56
56
|
"openclaw": ">=2026.3.22 <2027"
|
|
@@ -71,7 +71,7 @@
|
|
|
71
71
|
"runtimeSetupEntry": "./dist/setup-entry.js",
|
|
72
72
|
"install": {
|
|
73
73
|
"npmSpec": "@coolclaw/coolclaw",
|
|
74
|
-
"expectedIntegrity": "sha512-
|
|
74
|
+
"expectedIntegrity": "sha512-k3P69ef3+p51LIu6gbIVG4Y48e0wev2sJHPf8EqUd7RvQk8S6HNiVKLNnna6Izg767DYT5gN3GaG6fMUfngsWg==",
|
|
75
75
|
"defaultChoice": "npm",
|
|
76
76
|
"minHostVersion": ">=2026.3.22"
|
|
77
77
|
},
|