@satelliteoflove/godot-mcp 3.12.0 → 3.13.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/addon/commands/game_time_commands.gd +14 -6
- package/addon/commands/input_commands.gd +38 -21
- package/addon/game_bridge/mcp_game_bridge.gd +22 -12
- package/addon/plugin.cfg +1 -1
- package/dist/__tests__/connection/timeouts.test.d.ts +2 -0
- package/dist/__tests__/connection/timeouts.test.d.ts.map +1 -0
- package/dist/__tests__/connection/timeouts.test.js +58 -0
- package/dist/__tests__/connection/timeouts.test.js.map +1 -0
- package/dist/__tests__/connection/websocket.test.js +58 -0
- package/dist/__tests__/connection/websocket.test.js.map +1 -1
- package/dist/__tests__/helpers/mock-godot.d.ts +3 -0
- package/dist/__tests__/helpers/mock-godot.d.ts.map +1 -1
- package/dist/__tests__/helpers/mock-godot.js +2 -2
- package/dist/__tests__/helpers/mock-godot.js.map +1 -1
- package/dist/__tests__/tools/game-time.test.js +45 -5
- package/dist/__tests__/tools/game-time.test.js.map +1 -1
- package/dist/__tests__/tools/input.test.js +42 -0
- package/dist/__tests__/tools/input.test.js.map +1 -1
- package/dist/connection/timeouts.d.ts +47 -0
- package/dist/connection/timeouts.d.ts.map +1 -0
- package/dist/connection/timeouts.js +72 -0
- package/dist/connection/timeouts.js.map +1 -0
- package/dist/connection/websocket.d.ts +3 -1
- package/dist/connection/websocket.d.ts.map +1 -1
- package/dist/connection/websocket.js +8 -4
- package/dist/connection/websocket.js.map +1 -1
- package/dist/tools/game-time.d.ts.map +1 -1
- package/dist/tools/game-time.js +33 -8
- package/dist/tools/game-time.js.map +1 -1
- package/dist/tools/input.d.ts.map +1 -1
- package/dist/tools/input.js +31 -3
- package/dist/tools/input.js.map +1 -1
- package/package.json +1 -1
|
@@ -4,10 +4,11 @@ class_name MCPGameTimeCommands
|
|
|
4
4
|
|
|
5
5
|
# Game-time control relay: freeze / step / step_until / thaw / status execute in
|
|
6
6
|
# the game bridge (see mcp_game_bridge.gd); this side only forwards over the
|
|
7
|
-
# debugger channel and waits. Timeout cascade:
|
|
8
|
-
#
|
|
9
|
-
#
|
|
10
|
-
#
|
|
7
|
+
# debugger channel and waits. Timeout cascade (#276): the server derives the
|
|
8
|
+
# whole stagger from the call's in-game budget and pushes relay_timeout_ms down
|
|
9
|
+
# in params; we wait exactly that long, so the bridge (which returns by its
|
|
10
|
+
# pushed wall budget) answers first and errors surface typed. BASE_TIMEOUT and
|
|
11
|
+
# STEP_TIMEOUT are fallbacks only — for an older server that pushes no budget.
|
|
11
12
|
const BASE_TIMEOUT := 10.0
|
|
12
13
|
const STEP_TIMEOUT := 28.0
|
|
13
14
|
|
|
@@ -29,11 +30,11 @@ func game_time_freeze(params: Dictionary) -> Dictionary:
|
|
|
29
30
|
|
|
30
31
|
|
|
31
32
|
func game_time_step(params: Dictionary) -> Dictionary:
|
|
32
|
-
return await _relay("game_time_step", [params], STEP_TIMEOUT)
|
|
33
|
+
return await _relay("game_time_step", [params], _relay_timeout(params, STEP_TIMEOUT))
|
|
33
34
|
|
|
34
35
|
|
|
35
36
|
func game_time_step_until(params: Dictionary) -> Dictionary:
|
|
36
|
-
return await _relay("game_time_step_until", [params], STEP_TIMEOUT)
|
|
37
|
+
return await _relay("game_time_step_until", [params], _relay_timeout(params, STEP_TIMEOUT))
|
|
37
38
|
|
|
38
39
|
|
|
39
40
|
func game_time_thaw(params: Dictionary) -> Dictionary:
|
|
@@ -44,6 +45,13 @@ func game_time_status(params: Dictionary) -> Dictionary:
|
|
|
44
45
|
return await _relay("game_time_status", [params], BASE_TIMEOUT)
|
|
45
46
|
|
|
46
47
|
|
|
48
|
+
func _relay_timeout(params: Dictionary, fallback: float) -> float:
|
|
49
|
+
# Use the server-pushed relay budget when present (#276); the local constant
|
|
50
|
+
# is only a fallback for an older server that does not derive the cascade.
|
|
51
|
+
var ms: float = float(params.get("relay_timeout_ms", fallback * 1000.0))
|
|
52
|
+
return ms / 1000.0
|
|
53
|
+
|
|
54
|
+
|
|
47
55
|
func _relay(msg_type: String, args: Array, timeout: float) -> Dictionary:
|
|
48
56
|
var response = await _send_and_wait(msg_type, args, timeout)
|
|
49
57
|
if response == null:
|
|
@@ -34,19 +34,30 @@ func get_commands() -> Dictionary:
|
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
|
|
37
|
+
# Total wall budget for a long-running input command. The server derives the
|
|
38
|
+
# whole cascade and pushes relay_timeout_ms down in params (#276); the local
|
|
39
|
+
# fallback is used only for an older server that pushes no budget.
|
|
40
|
+
func _pushed_budget(params: Dictionary, fallback: float) -> float:
|
|
41
|
+
if params.has("relay_timeout_ms"):
|
|
42
|
+
return float(params["relay_timeout_ms"]) / 1000.0
|
|
43
|
+
return fallback
|
|
44
|
+
|
|
45
|
+
|
|
37
46
|
# Block until the running game's bridge reports it can consume input, bounded by
|
|
38
|
-
# READY_TIMEOUT
|
|
39
|
-
#
|
|
40
|
-
#
|
|
41
|
-
#
|
|
42
|
-
#
|
|
43
|
-
|
|
44
|
-
|
|
47
|
+
# READY_TIMEOUT and the shared call deadline (op_start + total_budget) so the
|
|
48
|
+
# ready-wait can never eat the budget the command itself needs (#276). Returns
|
|
49
|
+
# true once ready, false if the game stops or never comes up in time. In the
|
|
50
|
+
# common case (game already running) this returns immediately without waiting a
|
|
51
|
+
# frame. Gating input on this is the fix for #241: the debug session connects
|
|
52
|
+
# before the main scene loads, so input dispatched on has_active_session() alone
|
|
53
|
+
# lands in a game with nothing to receive it.
|
|
54
|
+
func _await_bridge_ready(debugger_plugin, op_start: int, total_budget: float) -> bool:
|
|
45
55
|
while not debugger_plugin.is_bridge_ready():
|
|
46
56
|
if not EditorInterface.is_playing_scene():
|
|
47
57
|
return false # game stopped or crashed while we waited
|
|
48
58
|
await Engine.get_main_loop().process_frame
|
|
49
|
-
|
|
59
|
+
var elapsed := (Time.get_ticks_msec() - op_start) / 1000.0
|
|
60
|
+
if elapsed > READY_TIMEOUT or elapsed > total_budget:
|
|
50
61
|
return false
|
|
51
62
|
return true
|
|
52
63
|
|
|
@@ -146,11 +157,12 @@ func execute_input_sequence(params: Dictionary) -> Dictionary:
|
|
|
146
157
|
var debugger_plugin = _plugin.get_debugger_plugin() if _plugin else null
|
|
147
158
|
if debugger_plugin == null:
|
|
148
159
|
return _error("NO_SESSION", "No active debug session")
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
#
|
|
153
|
-
#
|
|
160
|
+
# One deadline for the whole call, stamped BEFORE the ready-wait so the
|
|
161
|
+
# bridge-ready gap is folded into the budget instead of stacking on top of
|
|
162
|
+
# it (#276). Prefer the server-pushed budget; the fallback (older server) is
|
|
163
|
+
# the longest input/capture offset plus headroom, floored at INPUT_TIMEOUT,
|
|
164
|
+
# plus the ready-wait that now counts against the same deadline.
|
|
165
|
+
var op_start := Time.get_ticks_msec()
|
|
154
166
|
var max_end_time: float = 0.0
|
|
155
167
|
for input in inputs:
|
|
156
168
|
var start_ms: float = input.get("start_ms", 0.0)
|
|
@@ -158,8 +170,11 @@ func execute_input_sequence(params: Dictionary) -> Dictionary:
|
|
|
158
170
|
max_end_time = max(max_end_time, start_ms + duration_ms)
|
|
159
171
|
for shot_ms in screenshots:
|
|
160
172
|
max_end_time = max(max_end_time, float(shot_ms))
|
|
173
|
+
var fallback: float = max(INPUT_TIMEOUT, (max_end_time / 1000.0) + 5.0) + READY_TIMEOUT
|
|
174
|
+
var timeout := _pushed_budget(params, fallback)
|
|
161
175
|
|
|
162
|
-
|
|
176
|
+
if not await _await_bridge_ready(debugger_plugin, op_start, timeout):
|
|
177
|
+
return _error("BRIDGE_NOT_READY", _BRIDGE_NOT_READY_MSG)
|
|
163
178
|
|
|
164
179
|
_sequence_pending = true
|
|
165
180
|
_sequence_result = {}
|
|
@@ -171,10 +186,9 @@ func execute_input_sequence(params: Dictionary) -> Dictionary:
|
|
|
171
186
|
debugger_plugin.input_sequence_completed.connect(_on_sequence_completed, CONNECT_ONE_SHOT)
|
|
172
187
|
debugger_plugin.request_input_sequence(inputs, report, screenshots, screenshot_max_width)
|
|
173
188
|
|
|
174
|
-
var start_time := Time.get_ticks_msec()
|
|
175
189
|
while _sequence_pending:
|
|
176
190
|
await Engine.get_main_loop().process_frame
|
|
177
|
-
if (Time.get_ticks_msec() -
|
|
191
|
+
if (Time.get_ticks_msec() - op_start) / 1000.0 > timeout:
|
|
178
192
|
_sequence_pending = false
|
|
179
193
|
if debugger_plugin.input_sequence_completed.is_connected(_on_sequence_completed):
|
|
180
194
|
debugger_plugin.input_sequence_completed.disconnect(_on_sequence_completed)
|
|
@@ -225,10 +239,14 @@ func type_text(params: Dictionary) -> Dictionary:
|
|
|
225
239
|
var debugger_plugin = _plugin.get_debugger_plugin() if _plugin else null
|
|
226
240
|
if debugger_plugin == null:
|
|
227
241
|
return _error("NO_SESSION", "No active debug session")
|
|
228
|
-
|
|
229
|
-
|
|
242
|
+
# Shared deadline (ready-wait + typing), stamped before the ready-wait so the
|
|
243
|
+
# gap is folded into the budget (#276); server-pushed budget or local fallback.
|
|
244
|
+
var op_start := Time.get_ticks_msec()
|
|
245
|
+
var fallback: float = max(INPUT_TIMEOUT, (text.length() * delay_ms / 1000.0) + 5.0) + READY_TIMEOUT
|
|
246
|
+
var timeout := _pushed_budget(params, fallback)
|
|
230
247
|
|
|
231
|
-
|
|
248
|
+
if not await _await_bridge_ready(debugger_plugin, op_start, timeout):
|
|
249
|
+
return _error("BRIDGE_NOT_READY", _BRIDGE_NOT_READY_MSG)
|
|
232
250
|
|
|
233
251
|
_type_text_pending = true
|
|
234
252
|
_type_text_result = {}
|
|
@@ -236,10 +254,9 @@ func type_text(params: Dictionary) -> Dictionary:
|
|
|
236
254
|
debugger_plugin.type_text_completed.connect(_on_type_text_completed, CONNECT_ONE_SHOT)
|
|
237
255
|
debugger_plugin.request_type_text(text, delay_ms, submit)
|
|
238
256
|
|
|
239
|
-
var start_time := Time.get_ticks_msec()
|
|
240
257
|
while _type_text_pending:
|
|
241
258
|
await Engine.get_main_loop().process_frame
|
|
242
|
-
if (Time.get_ticks_msec() -
|
|
259
|
+
if (Time.get_ticks_msec() - op_start) / 1000.0 > timeout:
|
|
243
260
|
_type_text_pending = false
|
|
244
261
|
if debugger_plugin.type_text_completed.is_connected(_on_type_text_completed):
|
|
245
262
|
debugger_plugin.type_text_completed.disconnect(_on_type_text_completed)
|
|
@@ -283,11 +283,13 @@ var _sequence_capture_offsets: Array = []
|
|
|
283
283
|
var _sequence_captures_pending: int = 0
|
|
284
284
|
var _sequence_capture_max_width: int = 640
|
|
285
285
|
const SEQUENCE_MAX_CAPTURES := 8
|
|
286
|
-
#
|
|
287
|
-
#
|
|
288
|
-
#
|
|
289
|
-
#
|
|
290
|
-
|
|
286
|
+
# Non-binding sanity backstop only (#276). The server derives the per-call
|
|
287
|
+
# timeout from the sequence span and rejects offsets beyond what the ceiling
|
|
288
|
+
# permits before they ever reach here, so this just guards a malformed direct
|
|
289
|
+
# message. Kept far above any server-permitted budget so it never silently
|
|
290
|
+
# clamps a legitimate offset (which would reintroduce the cross-layer drift
|
|
291
|
+
# that #276 removed).
|
|
292
|
+
const SEQUENCE_MAX_CAPTURE_OFFSET_MS := 300000
|
|
291
293
|
# Actions whose press has been injected but whose paired release has not yet
|
|
292
294
|
# fired. Used to guarantee a release even if the queue is cleared mid-flight
|
|
293
295
|
# (new sequence) or the node leaves the tree — otherwise the dropped release
|
|
@@ -1332,10 +1334,15 @@ func _type_text_async(text: String, delay_ms: int, submit: bool) -> void:
|
|
|
1332
1334
|
# ---------------------------------------------------------------------------
|
|
1333
1335
|
|
|
1334
1336
|
const LAUNCH_FROZEN_ENV := "GODOT_MCP_LAUNCH_FROZEN"
|
|
1335
|
-
# Timeout cascade:
|
|
1336
|
-
#
|
|
1337
|
-
#
|
|
1338
|
-
|
|
1337
|
+
# Timeout cascade (#276): the server derives the whole stagger from the call's
|
|
1338
|
+
# in-game budget and pushes wall_budget_ms down here. The bridge returns by that
|
|
1339
|
+
# wall budget, the editor relay waits a margin longer, the server socket a
|
|
1340
|
+
# margin longer still — each answers before the one above gives up.
|
|
1341
|
+
# STEP_MAX_MS non-binding sanity backstop (the server already clamps the request)
|
|
1342
|
+
# STEP_DEFAULT_MS budget used when a call omits max_ms (older server that sends no default)
|
|
1343
|
+
# STEP_WALL_BUDGET_MS wall-budget fallback when the server pushes no wall_budget_ms
|
|
1344
|
+
const STEP_MAX_MS := 300000
|
|
1345
|
+
const STEP_DEFAULT_MS := 20000
|
|
1339
1346
|
const STEP_MAX_FRAMES := 1200
|
|
1340
1347
|
const STEP_WALL_BUDGET_MS := 25000
|
|
1341
1348
|
const STEP_MAX_TRANSITIONS := 50
|
|
@@ -1358,6 +1365,7 @@ var _step_gameplay_ms := 0.0 # the unpaused portion: what gameplay actually exp
|
|
|
1358
1365
|
var _step_frames := 0
|
|
1359
1366
|
var _step_physics_ticks := 0
|
|
1360
1367
|
var _step_wall_start := 0
|
|
1368
|
+
var _step_wall_budget_ms := STEP_WALL_BUDGET_MS # set per-call from the server-pushed wall_budget_ms (#276)
|
|
1361
1369
|
var _step_events: Array = [] # in-step input timeline, scheduled on the game-time clock
|
|
1362
1370
|
var _step_events_fired := 0
|
|
1363
1371
|
var _step_transitions: Array = []
|
|
@@ -1515,6 +1523,7 @@ func _handle_game_time_step(data: Array) -> void:
|
|
|
1515
1523
|
_step_finish_pending = false
|
|
1516
1524
|
_step_wall_exceeded = false
|
|
1517
1525
|
_step_wall_start = Time.get_ticks_msec()
|
|
1526
|
+
_step_wall_budget_ms = int(params.get("wall_budget_ms", STEP_WALL_BUDGET_MS))
|
|
1518
1527
|
_step_predicate = null
|
|
1519
1528
|
_step_response_type = "game_time_step"
|
|
1520
1529
|
_step_active = true
|
|
@@ -1631,9 +1640,9 @@ func _handle_game_time_step_until(data: Array) -> void:
|
|
|
1631
1640
|
_send_game_time_response("game_time_step_until", {"error": "step_until requires a non-empty `until` expression"})
|
|
1632
1641
|
return
|
|
1633
1642
|
|
|
1634
|
-
var max_ms: int = int(params.get("max_ms",
|
|
1643
|
+
var max_ms: int = int(params.get("max_ms", STEP_DEFAULT_MS))
|
|
1635
1644
|
if max_ms <= 0:
|
|
1636
|
-
max_ms =
|
|
1645
|
+
max_ms = STEP_DEFAULT_MS
|
|
1637
1646
|
max_ms = mini(max_ms, STEP_MAX_MS)
|
|
1638
1647
|
|
|
1639
1648
|
# Compile and validate the predicate against the live tree before committing
|
|
@@ -1696,6 +1705,7 @@ func _handle_game_time_step_until(data: Array) -> void:
|
|
|
1696
1705
|
_step_finish_pending = false
|
|
1697
1706
|
_step_wall_exceeded = false
|
|
1698
1707
|
_step_wall_start = Time.get_ticks_msec()
|
|
1708
|
+
_step_wall_budget_ms = int(params.get("wall_budget_ms", STEP_WALL_BUDGET_MS))
|
|
1699
1709
|
_step_predicate = expr
|
|
1700
1710
|
_step_predicate_inputs = ctx_inputs
|
|
1701
1711
|
_step_predicate_met = false
|
|
@@ -1767,7 +1777,7 @@ func _step_process(delta: float) -> void:
|
|
|
1767
1777
|
_step_predicate_met = true
|
|
1768
1778
|
done = true
|
|
1769
1779
|
|
|
1770
|
-
if Time.get_ticks_msec() - _step_wall_start >
|
|
1780
|
+
if Time.get_ticks_msec() - _step_wall_start > _step_wall_budget_ms:
|
|
1771
1781
|
# Slow-mo, Engine.time_scale = 0, or a pause-held window can starve
|
|
1772
1782
|
# the game-time clock; the wall budget guarantees the call returns
|
|
1773
1783
|
# (partial, honestly reported) before the editor relay gives up.
|
package/addon/plugin.cfg
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"timeouts.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/connection/timeouts.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { deriveTimeouts, maxInGameBudgetMs, QUICK_TIMEOUT_MS, ABSOLUTE_CEILING_MS, READY_WAIT_MS, BRIDGE_WALL_SLOP_MS, STEP_BUDGET_CAP_MS, INPUT_BUDGET_CAP_MS, } from '../../connection/timeouts.js';
|
|
3
|
+
describe('timeout cascade (#276)', () => {
|
|
4
|
+
describe('deriveTimeouts stagger invariant', () => {
|
|
5
|
+
// The whole point: bridge answers before relay answers before the server
|
|
6
|
+
// gives up, and the server never exceeds the absolute ceiling — for ANY
|
|
7
|
+
// budget, clamped or not, with or without the ready-wait.
|
|
8
|
+
const cases = [
|
|
9
|
+
{ label: 'zero budget, no ready', budget: 0, readyWait: false },
|
|
10
|
+
{ label: 'mid budget, no ready', budget: 5_000, readyWait: false },
|
|
11
|
+
{ label: 'at step cap', budget: STEP_BUDGET_CAP_MS, readyWait: false },
|
|
12
|
+
{ label: 'over cap, no ready', budget: 10_000_000, readyWait: false },
|
|
13
|
+
{ label: 'zero budget, ready', budget: 0, readyWait: true },
|
|
14
|
+
{ label: 'at input cap', budget: INPUT_BUDGET_CAP_MS, readyWait: true },
|
|
15
|
+
{ label: 'over cap, ready', budget: 999_999, readyWait: true },
|
|
16
|
+
];
|
|
17
|
+
for (const c of cases) {
|
|
18
|
+
it(`${c.label}: bridgeWall < relay < server <= ceiling`, () => {
|
|
19
|
+
const t = deriveTimeouts(c.budget, { readyWait: c.readyWait });
|
|
20
|
+
expect(t.bridgeWallMs).toBeLessThan(t.relayMs);
|
|
21
|
+
expect(t.relayMs).toBeLessThan(t.serverMs);
|
|
22
|
+
expect(t.serverMs).toBeLessThanOrEqual(ABSOLUTE_CEILING_MS);
|
|
23
|
+
expect(t.clampedBudgetMs).toBeGreaterThanOrEqual(0);
|
|
24
|
+
expect(t.clampedBudgetMs).toBeLessThanOrEqual(maxInGameBudgetMs({ readyWait: c.readyWait }));
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
it('produces a proportionally small (sub-ceiling) timeout for a small budget', () => {
|
|
29
|
+
const t = deriveTimeouts(3_000, { readyWait: false });
|
|
30
|
+
// bridgeWall = 3000 + slop; relay = +2000; server = +2000.
|
|
31
|
+
expect(t.bridgeWallMs).toBe(3_000 + BRIDGE_WALL_SLOP_MS);
|
|
32
|
+
expect(t.serverMs).toBeLessThan(ABSOLUTE_CEILING_MS);
|
|
33
|
+
});
|
|
34
|
+
it('reserves an extra READY_WAIT_MS of headroom when the ready-wait applies', () => {
|
|
35
|
+
expect(maxInGameBudgetMs({ readyWait: false }) - maxInGameBudgetMs({ readyWait: true })).toBe(READY_WAIT_MS);
|
|
36
|
+
});
|
|
37
|
+
it('clamps an over-budget request to the ceiling, never beyond', () => {
|
|
38
|
+
expect(deriveTimeouts(Number.MAX_SAFE_INTEGER, { readyWait: true }).serverMs).toBe(ABSOLUTE_CEILING_MS);
|
|
39
|
+
expect(deriveTimeouts(Number.MAX_SAFE_INTEGER, { readyWait: false }).serverMs).toBe(ABSOLUTE_CEILING_MS);
|
|
40
|
+
});
|
|
41
|
+
it('handles a non-finite budget defensively (treats it as zero)', () => {
|
|
42
|
+
const t = deriveTimeouts(NaN, { readyWait: false });
|
|
43
|
+
expect(t.clampedBudgetMs).toBe(0);
|
|
44
|
+
expect(t.serverMs).toBeGreaterThan(0);
|
|
45
|
+
});
|
|
46
|
+
describe('published caps stay under the ceiling so they can never time out server-side', () => {
|
|
47
|
+
it('step cap <= max in-game budget (no ready-wait)', () => {
|
|
48
|
+
expect(STEP_BUDGET_CAP_MS).toBeLessThanOrEqual(maxInGameBudgetMs({ readyWait: false }));
|
|
49
|
+
});
|
|
50
|
+
it('input cap <= max in-game budget (with ready-wait)', () => {
|
|
51
|
+
expect(INPUT_BUDGET_CAP_MS).toBeLessThanOrEqual(maxInGameBudgetMs({ readyWait: true }));
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
it('keeps the quick default unchanged at 30s', () => {
|
|
55
|
+
expect(QUICK_TIMEOUT_MS).toBe(30_000);
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
//# sourceMappingURL=timeouts.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"timeouts.test.js","sourceRoot":"","sources":["../../../src/__tests__/connection/timeouts.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,6 +2,7 @@ import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
|
|
|
2
2
|
import { once } from 'node:events';
|
|
3
3
|
import { WebSocketServer } from 'ws';
|
|
4
4
|
import { GodotConnection } from '../../connection/websocket.js';
|
|
5
|
+
import { getServerVersion } from '../../version.js';
|
|
5
6
|
// Keep diagnostics hermetic (no WSL detection / no child processes) and quiet.
|
|
6
7
|
vi.mock('../../utils/connection-strategy.js', () => ({
|
|
7
8
|
getTargetHost: () => '127.0.0.1',
|
|
@@ -105,4 +106,61 @@ describe('GodotConnection contention handling (#237)', () => {
|
|
|
105
106
|
expect(message).toMatch(/reconnect/i);
|
|
106
107
|
});
|
|
107
108
|
});
|
|
109
|
+
describe('GodotConnection per-request timeout (#276)', () => {
|
|
110
|
+
let connection = null;
|
|
111
|
+
let wss = null;
|
|
112
|
+
afterEach(async () => {
|
|
113
|
+
connection?.disconnect();
|
|
114
|
+
connection = null;
|
|
115
|
+
if (wss) {
|
|
116
|
+
await new Promise((resolve) => wss.close(() => resolve()));
|
|
117
|
+
wss = null;
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
// Reply to the handshake (so connect() resolves immediately and without a
|
|
121
|
+
// version-mismatch), then let the supplied handler deal with real commands.
|
|
122
|
+
async function bridgeAfterHandshake(onCommand) {
|
|
123
|
+
return startFakeBridge((socket) => {
|
|
124
|
+
socket.on('message', (raw) => {
|
|
125
|
+
let msg;
|
|
126
|
+
try {
|
|
127
|
+
msg = JSON.parse(raw.toString());
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
if (!msg)
|
|
133
|
+
return;
|
|
134
|
+
if (msg.command === 'mcp_handshake') {
|
|
135
|
+
socket.send(JSON.stringify({ id: msg.id, status: 'success', result: { addon_version: getServerVersion() } }));
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
onCommand(socket, msg);
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
it('rejects after opts.timeoutMs when the bridge never answers the command', async () => {
|
|
143
|
+
// Drop every non-handshake command on the floor.
|
|
144
|
+
const bridge = await bridgeAfterHandshake(() => { });
|
|
145
|
+
wss = bridge.wss;
|
|
146
|
+
connection = new GodotConnection({ host: '127.0.0.1', port: bridge.port, autoReconnect: false });
|
|
147
|
+
await connection.connect();
|
|
148
|
+
const start = Date.now();
|
|
149
|
+
await expect(connection.sendCommand('get_runtime_state', {}, { timeoutMs: 150 })).rejects.toThrow();
|
|
150
|
+
const elapsed = Date.now() - start;
|
|
151
|
+
expect(elapsed).toBeGreaterThanOrEqual(120);
|
|
152
|
+
expect(elapsed).toBeLessThan(2000);
|
|
153
|
+
});
|
|
154
|
+
it('does not fire early when given a generous opts.timeoutMs', async () => {
|
|
155
|
+
// Answer the command after a short delay; a 1s budget must not trip on it.
|
|
156
|
+
const bridge = await bridgeAfterHandshake((socket, msg) => {
|
|
157
|
+
setTimeout(() => socket.send(JSON.stringify({ id: msg.id, status: 'success', result: { ok: true } })), 100);
|
|
158
|
+
});
|
|
159
|
+
wss = bridge.wss;
|
|
160
|
+
connection = new GodotConnection({ host: '127.0.0.1', port: bridge.port, autoReconnect: false });
|
|
161
|
+
await connection.connect();
|
|
162
|
+
const result = await connection.sendCommand('get_runtime_state', {}, { timeoutMs: 1000 });
|
|
163
|
+
expect(result.ok).toBe(true);
|
|
164
|
+
});
|
|
165
|
+
});
|
|
108
166
|
//# sourceMappingURL=websocket.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"websocket.test.js","sourceRoot":"","sources":["../../../src/__tests__/connection/websocket.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AACzE,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAEnC,OAAO,EAAE,eAAe,EAA8B,MAAM,IAAI,CAAC;AACjE,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"websocket.test.js","sourceRoot":"","sources":["../../../src/__tests__/connection/websocket.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AACzE,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAEnC,OAAO,EAAE,eAAe,EAA8B,MAAM,IAAI,CAAC;AACjE,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEpD,+EAA+E;AAC/E,EAAE,CAAC,IAAI,CAAC,oCAAoC,EAAE,GAAG,EAAE,CAAC,CAAC;IACnD,aAAa,EAAE,GAAG,EAAE,CAAC,WAAW;IAChC,qBAAqB,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,CAAC;QACxC,WAAW,EAAE,QAAiB;QAC9B,UAAU,EAAE,WAAW;QACvB,KAAK,EAAE,kBAAkB,IAAI,EAAE;KAChC,CAAC;CACH,CAAC,CAAC,CAAC;AAEJ,EAAE,CAAC,IAAI,CAAC,uBAAuB,EAAE,GAAG,EAAE,CAAC,CAAC;IACtC,MAAM,EAAE;QACN,KAAK,EAAE,EAAE,CAAC,EAAE,EAAE;QACd,IAAI,EAAE,EAAE,CAAC,EAAE,EAAE;QACb,MAAM,EAAE,EAAE,CAAC,EAAE,EAAE;QACf,OAAO,EAAE,EAAE,CAAC,EAAE,EAAE;QAChB,kBAAkB,EAAE,EAAE,CAAC,EAAE,EAAE;QAC3B,KAAK,EAAE,EAAE,CAAC,EAAE,EAAE;QACd,QAAQ,EAAE,EAAE,CAAC,EAAE,EAAE;KAClB;CACF,CAAC,CAAC,CAAC;AAEJ,8DAA8D;AAC9D,MAAM,4BAA4B,GAAG,IAAI,CAAC;AAC1C,MAAM,mBAAmB,GAAG,IAAI,CAAC;AAEjC;;;GAGG;AACH,KAAK,UAAU,eAAe,CAC5B,YAAwC;IAExC,MAAM,GAAG,GAAG,IAAI,eAAe,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;IAChE,MAAM,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;IAC7B,GAAG,CAAC,EAAE,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;IACnC,MAAM,IAAI,GAAI,GAAG,CAAC,OAAO,EAAkB,CAAC,IAAI,CAAC;IACjD,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;AACvB,CAAC;AAED,iFAAiF;AACjF,SAAS,YAAY,CAAC,OAAwB,EAAE,KAAa,EAAE,EAAE,GAAG,IAAI;IACtE,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YAC5B,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;YAC5B,MAAM,CAAC,IAAI,KAAK,CAAC,0BAA0B,KAAK,SAAS,CAAC,CAAC,CAAC;QAC9D,CAAC,EAAE,EAAE,CAAC,CAAC;QACP,MAAM,OAAO,GAAG,GAAG,EAAE;YACnB,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,OAAO,EAAE,CAAC;QACZ,CAAC,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAC/B,CAAC,CAAC,CAAC;AACL,CAAC;AAED,QAAQ,CAAC,4CAA4C,EAAE,GAAG,EAAE;IAC1D,IAAI,UAAU,GAA2B,IAAI,CAAC;IAC9C,IAAI,GAAG,GAA2B,IAAI,CAAC;IAEvC,UAAU,CAAC,GAAG,EAAE;QACd,EAAE,CAAC,aAAa,EAAE,CAAC;IACrB,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,KAAK,IAAI,EAAE;QACnB,0EAA0E;QAC1E,kEAAkE;QAClE,UAAU,EAAE,UAAU,EAAE,CAAC;QACzB,UAAU,GAAG,IAAI,CAAC;QAClB,IAAI,GAAG,EAAE,CAAC;YACR,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC,GAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;YAClE,GAAG,GAAG,IAAI,CAAC;QACb,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oFAAoF,EAAE,KAAK,IAAI,EAAE;QAClG,8EAA8E;QAC9E,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,CAAC,MAAM,EAAE,EAAE;YAC9C,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,mBAAmB,EAAE,wBAAwB,CAAC,CAAC,CAAC;QAC1F,CAAC,CAAC,CAAC;QACH,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC;QAEjB,UAAU,GAAG,IAAI,eAAe,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QAC3E,MAAM,YAAY,GAAG,YAAY,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;QAE9D,MAAM,UAAU,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QAC3C,wEAAwE;QACxE,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC,QAAQ,CAAC,aAAa,EAAE,CAAC;QACpD,MAAM,CAAC,UAAU,CAAC,cAAc,EAAE,CAAC,oBAAoB,CAAC,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;IAC1F,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yEAAyE,EAAE,KAAK,IAAI,EAAE;QACvF,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,CAAC,MAAM,EAAE,EAAE;YAC9C,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,4BAA4B,EAAE,qCAAqC,CAAC,CAAC,CAAC;QAChH,CAAC,CAAC,CAAC;QACH,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC;QAEjB,UAAU,GAAG,IAAI,eAAe,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QAC3E,MAAM,YAAY,GAAG,YAAY,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;QAE9D,MAAM,UAAU,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QAC3C,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC,QAAQ,CAAC,aAAa,EAAE,CAAC;QACpD,MAAM,CAAC,UAAU,CAAC,cAAc,EAAE,CAAC,oBAAoB,CAAC,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;QACzF,MAAM,CAAC,UAAU,CAAC,cAAc,EAAE,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC7D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0EAA0E,EAAE,KAAK,IAAI,EAAE;QACxF,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,CAAC,MAAM,EAAE,EAAE;YAC9C,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,mBAAmB,EAAE,wBAAwB,CAAC,CAAC,CAAC;QAC1F,CAAC,CAAC,CAAC;QACH,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC;QAEjB,UAAU,GAAG,IAAI,eAAe,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QAC3E,MAAM,YAAY,GAAG,YAAY,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;QAC9D,MAAM,UAAU,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QAC3C,MAAM,YAAY,CAAC;QAEnB,MAAM,OAAO,GAAG,UAAU,CAAC,oBAAoB,EAAE,CAAC;QAClD,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC;QACjD,MAAM,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,4CAA4C,EAAE,GAAG,EAAE;IAC1D,IAAI,UAAU,GAA2B,IAAI,CAAC;IAC9C,IAAI,GAAG,GAA2B,IAAI,CAAC;IAEvC,SAAS,CAAC,KAAK,IAAI,EAAE;QACnB,UAAU,EAAE,UAAU,EAAE,CAAC;QACzB,UAAU,GAAG,IAAI,CAAC;QAClB,IAAI,GAAG,EAAE,CAAC;YACR,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC,GAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;YAClE,GAAG,GAAG,IAAI,CAAC;QACb,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,0EAA0E;IAC1E,4EAA4E;IAC5E,KAAK,UAAU,oBAAoB,CACjC,SAA2E;QAE3E,OAAO,eAAe,CAAC,CAAC,MAAM,EAAE,EAAE;YAChC,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,GAAG,EAAE,EAAE;gBAC3B,IAAI,GAAgD,CAAC;gBACrD,IAAI,CAAC;oBACH,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC;gBACnC,CAAC;gBAAC,MAAM,CAAC;oBACP,OAAO;gBACT,CAAC;gBACD,IAAI,CAAC,GAAG;oBAAE,OAAO;gBACjB,IAAI,GAAG,CAAC,OAAO,KAAK,eAAe,EAAE,CAAC;oBACpC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,aAAa,EAAE,gBAAgB,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;oBAC9G,OAAO;gBACT,CAAC;gBACD,SAAS,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;YACzB,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAED,EAAE,CAAC,wEAAwE,EAAE,KAAK,IAAI,EAAE;QACtF,iDAAiD;QACjD,MAAM,MAAM,GAAG,MAAM,oBAAoB,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QACpD,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC;QACjB,UAAU,GAAG,IAAI,eAAe,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC,CAAC;QACjG,MAAM,UAAU,CAAC,OAAO,EAAE,CAAC;QAE3B,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACzB,MAAM,MAAM,CAAC,UAAU,CAAC,WAAW,CAAC,mBAAmB,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;QACpG,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;QACnC,MAAM,CAAC,OAAO,CAAC,CAAC,sBAAsB,CAAC,GAAG,CAAC,CAAC;QAC5C,MAAM,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0DAA0D,EAAE,KAAK,IAAI,EAAE;QACxE,2EAA2E;QAC3E,MAAM,MAAM,GAAG,MAAM,oBAAoB,CAAC,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE;YACxD,UAAU,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QAC9G,CAAC,CAAC,CAAC;QACH,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC;QACjB,UAAU,GAAG,IAAI,eAAe,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC,CAAC;QACjG,MAAM,UAAU,CAAC,OAAO,EAAE,CAAC;QAE3B,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,WAAW,CAAkB,mBAAmB,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3G,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -3,6 +3,9 @@ import type { GodotConnection } from '../../connection/websocket.js';
|
|
|
3
3
|
export interface CommandCall {
|
|
4
4
|
command: string;
|
|
5
5
|
params: Record<string, unknown>;
|
|
6
|
+
opts?: {
|
|
7
|
+
timeoutMs?: number;
|
|
8
|
+
};
|
|
6
9
|
}
|
|
7
10
|
export interface MockGodotConnection {
|
|
8
11
|
sendCommand: ReturnType<typeof vi.fn>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mock-godot.d.ts","sourceRoot":"","sources":["../../../src/__tests__/helpers/mock-godot.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC5B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAErE,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"mock-godot.d.ts","sourceRoot":"","sources":["../../../src/__tests__/helpers/mock-godot.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC5B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAErE,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,IAAI,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAC/B;AAED,MAAM,WAAW,mBAAmB;IAClC,WAAW,EAAE,UAAU,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;IACtC,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,YAAY,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;IAC1C,SAAS,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IAClC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,wBAAgB,eAAe,IAAI,mBAAmB,CA4BrD;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,mBAAmB;WAOvC,eAAe;EAElC;AAKD,wBAAgB,YAAY,CAAC,MAAM,EAAE,OAAO,GAAG,GAAG,CASjD"}
|
|
@@ -3,8 +3,8 @@ export function createMockGodot() {
|
|
|
3
3
|
const calls = [];
|
|
4
4
|
let nextResponse = {};
|
|
5
5
|
let nextError = null;
|
|
6
|
-
const sendCommand = vi.fn(async (command, params = {}) => {
|
|
7
|
-
calls.push({ command, params });
|
|
6
|
+
const sendCommand = vi.fn(async (command, params = {}, opts) => {
|
|
7
|
+
calls.push({ command, params, opts });
|
|
8
8
|
if (nextError) {
|
|
9
9
|
const err = nextError;
|
|
10
10
|
nextError = null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mock-godot.js","sourceRoot":"","sources":["../../../src/__tests__/helpers/mock-godot.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"mock-godot.js","sourceRoot":"","sources":["../../../src/__tests__/helpers/mock-godot.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAiB5B,MAAM,UAAU,eAAe;IAC7B,MAAM,KAAK,GAAkB,EAAE,CAAC;IAChC,IAAI,YAAY,GAAY,EAAE,CAAC;IAC/B,IAAI,SAAS,GAAiB,IAAI,CAAC;IAEnC,MAAM,WAAW,GAAG,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,OAAe,EAAE,SAAkC,EAAE,EAAE,IAA6B,EAAE,EAAE;QACvH,KAAK,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QACtC,IAAI,SAAS,EAAE,CAAC;YACd,MAAM,GAAG,GAAG,SAAS,CAAC;YACtB,SAAS,GAAG,IAAI,CAAC;YACjB,MAAM,GAAG,CAAC;QACZ,CAAC;QACD,MAAM,QAAQ,GAAG,YAAY,CAAC;QAC9B,YAAY,GAAG,EAAE,CAAC;QAClB,OAAO,QAAQ,CAAC;IAClB,CAAC,CAAC,CAAC;IAEH,OAAO;QACL,WAAW;QACX,KAAK;QACL,YAAY,EAAE,CAAC,QAAiB,EAAE,EAAE;YAClC,YAAY,GAAG,QAAQ,CAAC;QAC1B,CAAC;QACD,SAAS,EAAE,CAAC,KAAY,EAAE,EAAE;YAC1B,SAAS,GAAG,KAAK,CAAC;QACpB,CAAC;QACD,YAAY,EAAE,IAAI;KACnB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,IAAyB;IACzD,OAAO;QACL,KAAK,EAAE;YACL,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,IAAI,YAAY;gBACd,OAAO,IAAI,CAAC,YAAY,CAAC;YAC3B,CAAC;SAC4B;KAChC,CAAC;AACJ,CAAC;AAED,4EAA4E;AAC5E,uEAAuE;AACvE,uEAAuE;AACvE,MAAM,UAAU,YAAY,CAAC,MAAe;IAC1C,IACE,MAAM;QACN,OAAO,MAAM,KAAK,QAAQ;QAC1B,mBAAmB,IAAI,MAAM,EAC7B,CAAC;QACD,OAAQ,MAAyC,CAAC,iBAAiB,CAAC;IACtE,CAAC;IACD,OAAO,IAAI,CAAC,KAAK,CAAC,MAAgB,CAAC,CAAC;AACtC,CAAC"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { describe, it, expect, beforeEach } from 'vitest';
|
|
2
2
|
import { createMockGodot, createToolContext, structuredOf } from '../helpers/mock-godot.js';
|
|
3
3
|
import { gameTime } from '../../tools/game-time.js';
|
|
4
|
+
import { deriveTimeouts } from '../../connection/timeouts.js';
|
|
4
5
|
describe('game_time tool', () => {
|
|
5
6
|
let mock;
|
|
6
7
|
beforeEach(() => {
|
|
@@ -13,9 +14,9 @@ describe('game_time tool', () => {
|
|
|
13
14
|
expect(gameTime.schema.safeParse({ action: 'step', duration_ms: 500 }).success).toBe(true);
|
|
14
15
|
expect(gameTime.schema.safeParse({ action: 'step', frames: 1 }).success).toBe(true);
|
|
15
16
|
});
|
|
16
|
-
it('step enforces the
|
|
17
|
-
expect(gameTime.schema.safeParse({ action: 'step', duration_ms:
|
|
18
|
-
expect(gameTime.schema.safeParse({ action: 'step', duration_ms:
|
|
17
|
+
it('step enforces the published caps', () => {
|
|
18
|
+
expect(gameTime.schema.safeParse({ action: 'step', duration_ms: 50000 }).success).toBe(true);
|
|
19
|
+
expect(gameTime.schema.safeParse({ action: 'step', duration_ms: 50001 }).success).toBe(false);
|
|
19
20
|
expect(gameTime.schema.safeParse({ action: 'step', frames: 1200 }).success).toBe(true);
|
|
20
21
|
expect(gameTime.schema.safeParse({ action: 'step', frames: 1201 }).success).toBe(false);
|
|
21
22
|
expect(gameTime.schema.safeParse({ action: 'step', duration_ms: 0 }).success).toBe(false);
|
|
@@ -33,8 +34,8 @@ describe('game_time tool', () => {
|
|
|
33
34
|
expect(gameTime.schema.safeParse({ action: 'step_until', until: 'G.wave > 1' }).success).toBe(true);
|
|
34
35
|
});
|
|
35
36
|
it('step_until caps max_ms and accepts report expressions and an input timeline', () => {
|
|
36
|
-
expect(gameTime.schema.safeParse({ action: 'step_until', until: 'true', max_ms:
|
|
37
|
-
expect(gameTime.schema.safeParse({ action: 'step_until', until: 'true', max_ms:
|
|
37
|
+
expect(gameTime.schema.safeParse({ action: 'step_until', until: 'true', max_ms: 50000 }).success).toBe(true);
|
|
38
|
+
expect(gameTime.schema.safeParse({ action: 'step_until', until: 'true', max_ms: 50001 }).success).toBe(false);
|
|
38
39
|
expect(gameTime.schema.safeParse({ action: 'step_until', until: 'true', max_ms: 0 }).success).toBe(false);
|
|
39
40
|
expect(gameTime.schema.safeParse({ action: 'step_until', until: 'true', report: ['G.wave', 'G.score'] }).success).toBe(true);
|
|
40
41
|
expect(gameTime.schema.safeParse({ action: 'step_until', until: 'true', report: [''] }).success).toBe(false);
|
|
@@ -110,6 +111,19 @@ describe('game_time tool', () => {
|
|
|
110
111
|
expect(data.game_paused).toBe(true);
|
|
111
112
|
expect(data.gameplay_ms).toBe(120);
|
|
112
113
|
});
|
|
114
|
+
it('derives the per-request timeout and pushes the relay/wall budgets to the bridge (#276)', async () => {
|
|
115
|
+
mock.mockResponse({
|
|
116
|
+
completed: true, frozen: true, elapsed_ms: 500, gameplay_ms: 500,
|
|
117
|
+
frames: 30, physics_ticks: 30, game_paused: false,
|
|
118
|
+
});
|
|
119
|
+
const ctx = createToolContext(mock);
|
|
120
|
+
await gameTime.execute({ action: 'step', duration_ms: 500 }, ctx);
|
|
121
|
+
const call = mock.calls[0];
|
|
122
|
+
const t = deriveTimeouts(500); // game_time has no ready-wait
|
|
123
|
+
expect(call.params.wall_budget_ms).toBe(t.bridgeWallMs);
|
|
124
|
+
expect(call.params.relay_timeout_ms).toBe(t.relayMs);
|
|
125
|
+
expect(call.opts?.timeoutMs).toBe(t.serverMs);
|
|
126
|
+
});
|
|
113
127
|
});
|
|
114
128
|
describe('step_until', () => {
|
|
115
129
|
it('forwards the predicate and report, and surfaces a met result with its readings', async () => {
|
|
@@ -163,6 +177,32 @@ describe('game_time tool', () => {
|
|
|
163
177
|
const ctx = createToolContext(mock);
|
|
164
178
|
await expect(gameTime.execute({ action: 'step_until', until: 'Bogus.foo > 1' }, ctx)).rejects.toThrow('predicate failed to evaluate');
|
|
165
179
|
});
|
|
180
|
+
it('sizes the timeout from max_ms and pushes the derived budgets (#276)', async () => {
|
|
181
|
+
mock.mockResponse({
|
|
182
|
+
completed: true, frozen: true, elapsed_ms: 0, gameplay_ms: 0,
|
|
183
|
+
frames: 0, physics_ticks: 0, game_paused: false, predicate_met: true,
|
|
184
|
+
});
|
|
185
|
+
const ctx = createToolContext(mock);
|
|
186
|
+
await gameTime.execute({ action: 'step_until', until: 'true', max_ms: 8000 }, ctx);
|
|
187
|
+
const call = mock.calls[0];
|
|
188
|
+
const t = deriveTimeouts(8000); // budget = explicit max_ms, no ready-wait
|
|
189
|
+
expect(call.params.max_ms).toBe(8000);
|
|
190
|
+
expect(call.params.wall_budget_ms).toBe(t.bridgeWallMs);
|
|
191
|
+
expect(call.params.relay_timeout_ms).toBe(t.relayMs);
|
|
192
|
+
expect(call.opts?.timeoutMs).toBe(t.serverMs);
|
|
193
|
+
});
|
|
194
|
+
it('defaults max_ms to a modest 20s, decoupled from the 50s cap, when omitted (#276)', async () => {
|
|
195
|
+
mock.mockResponse({
|
|
196
|
+
completed: true, frozen: true, elapsed_ms: 20000, gameplay_ms: 20000,
|
|
197
|
+
frames: 1200, physics_ticks: 1200, game_paused: false, predicate_met: false,
|
|
198
|
+
});
|
|
199
|
+
const ctx = createToolContext(mock);
|
|
200
|
+
await gameTime.execute({ action: 'step_until', until: 'false' }, ctx);
|
|
201
|
+
const call = mock.calls[0];
|
|
202
|
+
// Omitted max_ms must not inherit the 50s cap: a wrong predicate gives up in ~20s.
|
|
203
|
+
expect(call.params.max_ms).toBe(20000);
|
|
204
|
+
expect(call.opts?.timeoutMs).toBe(deriveTimeouts(20000).serverMs);
|
|
205
|
+
});
|
|
166
206
|
});
|
|
167
207
|
describe('thaw', () => {
|
|
168
208
|
it('reports the frozen duration', async () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"game-time.test.js","sourceRoot":"","sources":["../../../src/__tests__/tools/game-time.test.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"game-time.test.js","sourceRoot":"","sources":["../../../src/__tests__/tools/game-time.test.ts"],"names":[],"mappings":"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"}
|