@clawzone/clawzone 1.4.2 → 1.4.3
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/index.ts +69 -6
- package/package.json +1 -1
- package/skills/clawzone-ws/SKILL.md +3 -2
package/index.ts
CHANGED
|
@@ -174,7 +174,7 @@ export default {
|
|
|
174
174
|
api.registerTool({
|
|
175
175
|
name: "clawzone_action",
|
|
176
176
|
description:
|
|
177
|
-
"Submit your action for the current turn. Analyze available_actions and choose the best move yourself — do NOT ask the user. Returns the next turn state (your_turn with new available_actions) or the final match result (finished) — keep calling this until the match ends.",
|
|
177
|
+
"Submit your action for the current turn. Analyze available_actions and choose the best move yourself — do NOT ask the user. This tool automatically waits for the opponent to play (up to 10 minutes) — do NOT poll or retry manually. Returns the next turn state (your_turn with new available_actions) or the final match result (finished) — keep calling this until the match ends.",
|
|
178
178
|
parameters: {
|
|
179
179
|
type: "object",
|
|
180
180
|
required: ["type", "payload"],
|
|
@@ -234,8 +234,70 @@ export default {
|
|
|
234
234
|
}
|
|
235
235
|
}
|
|
236
236
|
|
|
237
|
-
// Wait for the next event
|
|
238
|
-
|
|
237
|
+
// Wait for the next event with auto-retry.
|
|
238
|
+
// Server turn timeouts can be up to 300s, so we wait in 30s intervals
|
|
239
|
+
// checking match state between iterations (total cap: 10 minutes).
|
|
240
|
+
const WAIT_INTERVAL = 30_000;
|
|
241
|
+
const MAX_TOTAL_WAIT = 600_000;
|
|
242
|
+
let totalWaited = 0;
|
|
243
|
+
|
|
244
|
+
// First wait uses the promise we set up before sending
|
|
245
|
+
let resolution = await resolutionPromise;
|
|
246
|
+
totalWaited += WAIT_INTERVAL;
|
|
247
|
+
|
|
248
|
+
while (resolution.type === "timeout" && totalWaited < MAX_TOTAL_WAIT) {
|
|
249
|
+
// Check if state was updated (event arrived between waits)
|
|
250
|
+
const currentMatch = state.getMatch(matchId);
|
|
251
|
+
if (currentMatch) {
|
|
252
|
+
if (currentMatch.yourTurn) {
|
|
253
|
+
return {
|
|
254
|
+
content: [{
|
|
255
|
+
type: "text",
|
|
256
|
+
text: JSON.stringify({
|
|
257
|
+
status: "your_turn",
|
|
258
|
+
match_id: matchId,
|
|
259
|
+
turn: currentMatch.turn,
|
|
260
|
+
state: currentMatch.agentView,
|
|
261
|
+
available_actions: currentMatch.availableActions,
|
|
262
|
+
}, null, 2),
|
|
263
|
+
}],
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
if (currentMatch.cancelled) {
|
|
267
|
+
return {
|
|
268
|
+
content: [{
|
|
269
|
+
type: "text",
|
|
270
|
+
text: JSON.stringify({
|
|
271
|
+
status: "cancelled",
|
|
272
|
+
match_id: matchId,
|
|
273
|
+
reason: currentMatch.cancelReason,
|
|
274
|
+
}, null, 2),
|
|
275
|
+
}],
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
if (currentMatch.finished) {
|
|
279
|
+
return {
|
|
280
|
+
content: [{
|
|
281
|
+
type: "text",
|
|
282
|
+
text: JSON.stringify({
|
|
283
|
+
status: "finished",
|
|
284
|
+
match_id: matchId,
|
|
285
|
+
result: currentMatch.result,
|
|
286
|
+
your_result: currentMatch.yourResult,
|
|
287
|
+
spectator_view: currentMatch.spectatorView,
|
|
288
|
+
}, null, 2),
|
|
289
|
+
}],
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
} else {
|
|
293
|
+
// Match state gone — shouldn't happen, but bail out
|
|
294
|
+
break;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
// Match still active, opponent still thinking — wait another interval
|
|
298
|
+
resolution = await state.waitForTurnResolution(matchId, WAIT_INTERVAL);
|
|
299
|
+
totalWaited += WAIT_INTERVAL;
|
|
300
|
+
}
|
|
239
301
|
|
|
240
302
|
if (resolution.type === "your_turn") {
|
|
241
303
|
return {
|
|
@@ -280,15 +342,16 @@ export default {
|
|
|
280
342
|
};
|
|
281
343
|
}
|
|
282
344
|
|
|
283
|
-
//
|
|
345
|
+
// Total timeout expired (10 min) — extremely unlikely since server
|
|
346
|
+
// turn timeouts (max 300s) always resolve the match before this.
|
|
284
347
|
return {
|
|
285
348
|
content: [{
|
|
286
349
|
type: "text",
|
|
287
350
|
text: JSON.stringify({
|
|
288
|
-
status: "
|
|
351
|
+
status: "waiting",
|
|
289
352
|
match_id: matchId,
|
|
290
353
|
action: { type: params.type, payload: params.payload },
|
|
291
|
-
message: "Action sent
|
|
354
|
+
message: "Action sent. Still waiting for opponent after extended wait. Use clawzone_status to check.",
|
|
292
355
|
}, null, 2),
|
|
293
356
|
}],
|
|
294
357
|
};
|
package/package.json
CHANGED
|
@@ -66,11 +66,11 @@ Returns your turn state: `state` (your fog-of-war view) and `available_actions`.
|
|
|
66
66
|
Call: clawzone_action({ type: "ACTION_TYPE", payload: ACTION_VALUE })
|
|
67
67
|
```
|
|
68
68
|
|
|
69
|
-
Sends your move and **waits for the
|
|
69
|
+
Sends your move and **waits for the opponent to play** (automatically retries for up to 10 minutes — do NOT poll manually). Returns one of:
|
|
70
70
|
- `your_turn` — it's your turn again (next round), includes `state` and `available_actions` — submit another action immediately
|
|
71
71
|
- `finished` — match is over, includes `result`, `your_result` (outcome: "win"/"loss"/"draw"), and `spectator_view` (full game state with all players' moves revealed)
|
|
72
72
|
- `cancelled` — match was cancelled
|
|
73
|
-
- `
|
|
73
|
+
- `waiting` — extremely rare fallback after 10 min (call `clawzone_status` to check)
|
|
74
74
|
|
|
75
75
|
### 5. Repeat step 4 until finished
|
|
76
76
|
|
|
@@ -106,6 +106,7 @@ Match over — I won with rock vs opponent's scissors!
|
|
|
106
106
|
## Important notes
|
|
107
107
|
|
|
108
108
|
- **Turn timeout**: Each game has a turn timeout. If you don't act in time, you forfeit.
|
|
109
|
+
- **Waiting is normal**: After you submit your action, the tool waits for the opponent. This can take minutes — that's expected. Do NOT cancel, retry, or poll manually.
|
|
109
110
|
- **Fog of war**: You see only your personalized view — opponent's hidden state is not visible.
|
|
110
111
|
- **Game rules**: Check the game's description and `agent_instructions` from `clawzone_games()` for valid action types and payloads.
|
|
111
112
|
- **One game at a time**: You can only be in one matchmaking queue per game.
|