Add cursor polling for editor logs#559
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
Pull request overview
This PR completes the editor-log cursor work from #555 by exposing cursor-based incremental reads for editor logs via logs_read(source="editor", since_cursor=N), enabling agents to poll for new editor diagnostics without rereading the entire buffer.
Changes:
- Adds
since_cursorsupport end-to-end (Python tool wrapper → Python handler → GodotEditorHandler.get_logs) for cursor-based editor log polling. - Extends editor log responses to include cursor metadata (
next_cursor,appended_total, and in cursor mode:cursor,oldest_cursor,truncated,has_more). - Adds/updates unit, integration, and in-editor GDScript tests and documents the cursor contract.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
src/godot_ai/tools/editor.py |
Adds since_cursor parameter to the public MCP logs_read tool and documents the cursor polling contract. |
src/godot_ai/handlers/editor.py |
Threads since_cursor into the plugin command and passes through cursor metadata fields when present. |
plugin/addons/godot_ai/handlers/editor_handler.gd |
Implements cursor-mode editor log reads (get_since) and returns cursor metadata; regular reads now return next_cursor/appended_total. |
docs/TOOLS.md |
Documents how to use next_cursor/since_cursor for incremental editor-log polling and explains truncation semantics. |
tests/unit/test_runtime_handlers.py |
Adds handler-level coverage for since_cursor pass-through and validates new cursor fields on regular editor reads. |
tests/integration/test_mcp_tools.py |
Adds MCP integration coverage ensuring since_cursor is passed through and cursor metadata is returned. |
test_project/tests/test_editor.gd |
Adds in-editor tests validating regular cursor establishment, incremental reads, truncation behavior, and Debugger Errors-tab exclusion in cursor mode. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
Thanks @Clubhouse1661 — clean completion of the #555 cursor work. |
Summary
This finishes the editor-log cursor work started in #555.
#555 added the monotonic cursor primitive to
McpEditorLogBuffer, but there was not yet an agent-facing way to use it. This PR exposes that primitive throughlogs_read(source="editor", since_cursor=N), so agents can poll for new editor diagnostics without rereading the whole editor log buffer.What changed
since_cursorsupport tologs_read(source="editor").next_cursorandappended_total, so callers can establish a cursor.cursoroldest_cursornext_cursorappended_totaltruncatedhas_moresince_cursorthrough the Python tool wrapper and handler intoEditorHandler.get_logs.docs/TOOLS.md.One deliberate design choice:
since_cursormode reads only Logger-backed editor entries. Debugger Errors-tab rows are live editor UI state with no stable sequence number, so they cannot be cursor-paged. Regularlogs_read(source="editor")calls still merge those Debugger rows as before.Notes for callers
logs_read(source="editor")and savenext_cursor.since_cursor=<saved cursor>to receive only newer Logger-backed editor entries.since_cursorsupersedesoffset.truncated: truemeans the caller fell behind the ring and some entries were evicted before polling. Continue from the returnednext_cursor;oldest_cursoris the earliest retained sequence.next_cursor.Verification
uv run pytest tests\unit\test_runtime_handlers.py -k logs_read: 9 passeduv run pytest tests\integration\test_mcp_tools.py::TestLogsReadTool: 6 passeduv run pytest tests\unit\test_tool_domains.py: 13 passedgit diff --check: passedtest_run suite="editor"on Godot 4.6.3: 127 passed, 2 skipped, 0 failedCI’s Godot 4.3 canary should cover the older-engine/null-buffer path where the Logger API is unavailable.