mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-10-19 20:44:16 +02:00
qet MCP: keep the edit script's report lines when cutting long output
_run_qet() kept only the last 400 000 characters of a run's output. A large qet_edit (a whole multi-folio drawing in one call, some 2000 ops) logs more than that, and the cut took the capability report the script makes first: the tool then answered "the binary never ran the script" although QElectroTech had run it and saved the result. Lines the script reports through its marker are now kept whole wherever they stand; only the other output is cut to the tail. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+18
-1
@@ -1072,6 +1072,23 @@ def _user_collections() -> dict:
|
||||
return found
|
||||
|
||||
|
||||
def _keep_tail(text: str, tail: int) -> str:
|
||||
"""The last `tail` characters of a run's output, but every line an edit
|
||||
script reported through its marker kept whole, wherever it stands.
|
||||
|
||||
A large qet_edit logs far more than `tail` characters; cut from the
|
||||
front, it lost the capability report the script makes first, and the
|
||||
tool then said the binary had never run the script."""
|
||||
if len(text) <= tail:
|
||||
return text
|
||||
marked = [ln for ln in text.splitlines() if "QETEDIT " in ln]
|
||||
rest = text[-tail:]
|
||||
if not marked:
|
||||
return rest
|
||||
kept = set(rest.splitlines())
|
||||
return "\n".join([ln for ln in marked if ln not in kept] + [rest])
|
||||
|
||||
|
||||
def _run_qet(binary: str, args: list[str], timeout: int = 180,
|
||||
elements_dir: str | None = None,
|
||||
script: str | None = None, tail: int = 4000,
|
||||
@@ -1150,7 +1167,7 @@ def _run_qet(binary: str, args: list[str], timeout: int = 180,
|
||||
"hint": "a modal dialog during load will hang a headless "
|
||||
"run; check the project's format version"}
|
||||
result = {"ok": p.returncode == 0, "exit_code": p.returncode,
|
||||
"stdout": p.stdout[-tail:], "stderr": p.stderr[-tail:]}
|
||||
"stdout": _keep_tail(p.stdout, tail), "stderr": _keep_tail(p.stderr, tail)}
|
||||
# QElectroTech refuses --run when scripting is switched off, which
|
||||
# it is by default. Its own message is clear but French, and it
|
||||
# names a settings dialog that nobody driving this server is
|
||||
|
||||
@@ -6626,6 +6626,23 @@ class ZippedProjects(unittest.TestCase):
|
||||
self.assertNotEqual(*rotated[0]["orientation"])
|
||||
|
||||
|
||||
class TestKeepTail(unittest.TestCase):
|
||||
"""A large edit logs more than the kept tail; the script's own report
|
||||
lines must survive the cut, or qet_edit says the script never ran."""
|
||||
|
||||
def test_short_output_is_untouched(self):
|
||||
self.assertEqual(m._keep_tail("a\nb", 100), "a\nb")
|
||||
|
||||
def test_marker_lines_survive_the_cut(self):
|
||||
first = 'QETEDIT {"kind": "capabilities", "missing": []}'
|
||||
text = first + "\n" + "x" * 1000 + "\n" + 'QETEDIT {"kind": "save", "result": true}'
|
||||
kept = m._keep_tail(text, 100)
|
||||
self.assertIn(first, kept)
|
||||
self.assertIn('"kind": "save"', kept)
|
||||
self.assertEqual(kept.count('"kind": "save"'), 1)
|
||||
self.assertEqual(m._parse_script_output(kept).get("missing_methods"), [])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print(f"binary : {BINARY or '(none: integration tests skipped)'}")
|
||||
print(f"elements : {ELEMENTS or '(none)'}")
|
||||
|
||||
Reference in New Issue
Block a user