Add relay_json module, update dialogue and file_ops, update local settings
This commit is contained in:
@@ -264,3 +264,66 @@ def test_write_creates_parent_directories(tmp_path):
|
||||
action = file_ops.parse(_cmd({"op": "write", "path": str(target), "content": "hi"}))
|
||||
file_ops.execute(action)
|
||||
assert target.read_text() == "hi"
|
||||
|
||||
|
||||
# ── lenient JSON (see relay_json) ───────────────────────────────────────────
|
||||
# Machine-written JSON fails in a small, repeatable set of ways. Observed live
|
||||
# 2026-07-30: a stray quote after `false` cost a whole desk turn — rejected,
|
||||
# re-sent identically, rejected again, then abandoned with a promise to the
|
||||
# user that nothing fulfilled.
|
||||
|
||||
def test_the_stray_quote_that_cost_a_live_turn_now_parses():
|
||||
action = file_ops.parse(
|
||||
'filectl {"op":"list","path":"/home/maji/Documents","pattern":"*","recursive":false"}'
|
||||
)
|
||||
assert action["action"] == "list"
|
||||
assert action["path"] == "/home/maji/Documents"
|
||||
assert action["recursive"] is False
|
||||
assert action["_repairs"] == ["removed a stray quote after a bare value"]
|
||||
|
||||
|
||||
@pytest.mark.parametrize("payload,expected", [
|
||||
('{"op": "read", "path": "/tmp/a.txt",}', "removed a trailing comma"),
|
||||
("{'op': 'read', 'path': '/tmp/a.txt'}", "converted single-quoted strings to double-quoted"),
|
||||
('{“op”: “read”, “path”: “/tmp/a.txt”}', "replaced smart quotes with straight ones"),
|
||||
('```json {"op": "read", "path": "/tmp/a.txt"} ```', "stripped a markdown code fence"),
|
||||
])
|
||||
def test_common_model_json_mistakes_are_repaired(payload, expected):
|
||||
action = file_ops.parse("filectl " + payload)
|
||||
assert action["action"] == "read"
|
||||
assert action["path"] == "/tmp/a.txt"
|
||||
assert expected in action["_repairs"]
|
||||
|
||||
|
||||
def test_python_literals_are_converted():
|
||||
action = file_ops.parse('filectl {"op": "list", "path": "/tmp", "recursive": True}')
|
||||
assert action["recursive"] is True
|
||||
|
||||
|
||||
def test_a_repair_is_reported_in_the_output_never_hidden(tmp_path):
|
||||
"""Silently fixing it would work today and guarantee the same broken call
|
||||
tomorrow — the model has to be told while it still has the turn."""
|
||||
(tmp_path / "a.txt").write_text("hello", encoding="utf-8")
|
||||
action = file_ops.parse(
|
||||
'filectl {"op":"list","path":"%s","recursive":false"}' % tmp_path
|
||||
)
|
||||
output = file_ops.execute(action)
|
||||
assert "a.txt" in output
|
||||
assert "your JSON was malformed" in output
|
||||
assert "stray quote" in output
|
||||
|
||||
|
||||
def test_valid_json_gets_no_repair_note(tmp_path):
|
||||
(tmp_path / "a.txt").write_text("hello", encoding="utf-8")
|
||||
action = file_ops.parse('filectl {"op": "list", "path": "%s"}' % tmp_path)
|
||||
assert "_repairs" not in action
|
||||
assert "malformed" not in file_ops.execute(action)
|
||||
|
||||
|
||||
def test_genuinely_unparseable_json_points_at_the_character():
|
||||
""""Expecting ',' delimiter: char 74" is not something a model can act on."""
|
||||
with pytest.raises(file_ops.FileOpError) as excinfo:
|
||||
file_ops.parse('filectl {"op": "read", "path": "/tmp/a.txt" "extra": 1}')
|
||||
message = str(excinfo.value)
|
||||
assert "^" in message # caret under the offending character
|
||||
assert '"extra"' in message # ...and the fragment around it
|
||||
|
||||
Reference in New Issue
Block a user