Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,17 @@ export const conversationReturnContinuityScenario = {
if (api.turnRequests.at(-1).sessionId === oldSessionId) throw new Error("Fixture did not replace the active session");
const turnsBeforeReturn = api.turnRequests.length;
let droppedRead = false;
await page.route(`**/api/chat/sessions/${oldSessionId}`, async (route) => {
const failedRead = page.waitForEvent("requestfailed", {
predicate: (request) => new URL(request.url()).pathname === `/api/chat/sessions/${oldSessionId}`,
timeout: 10_000,
});
await page.route((url) => url.pathname === `/api/chat/sessions/${oldSessionId}`, async (route) => {
if (!droppedRead) { droppedRead = true; await route.abort("connectionreset"); }
else await route.fallback();
});
// A streamed return can arrive before the next snapshot poll. Observe
// the injected read failure before publishing the late result.
await failedRead;
const answer = "核对完成:现金流期间和单位一致。";
page.__loopxRuntime.messages.get(oldSessionId).push({
message_id: "handoff.old-result", turn_id: "old-turn", role: "agent", origin: "manager_followup",
Expand Down
40 changes: 40 additions & 0 deletions tests/control_plane/test_replan_progress_native_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,12 @@ def make_progress_cli_fixture(root: Path, provider: str, scenario: str) -> dict:


def call_progress_cli(fixture: dict, *args: str, expected_code: int = 0) -> dict:
# These tests inspect the authority decision, independently of machine
# presentation defaults. Preserve explicit context delivery overrides.
if args[:2] == ("quota", "should-run") and not any(
arg == "--context-delivery" or arg.startswith("--context-delivery=") for arg in args
):
args = (*args, "--context-delivery", "off")
result = subprocess.run([
sys.executable, "-m", "loopx.cli", "--registry", str(fixture["registry"]),
"--runtime-root", str(fixture["runtime"]), "--format", "json", *args,
Expand All @@ -124,6 +130,40 @@ def call_progress_cli(fixture: dict, *args: str, expected_code: int = 0) -> dict
return json.loads(result.stdout)


@pytest.mark.parametrize("provider", ["file", "sqlite"])
@pytest.mark.parametrize("context_args,navigation", [
((), False),
(("--context-delivery", "on"), True),
(("--context-delivery=on",), True),
(("--context-delivery", "off"), False),
(("--context-delivery=off",), False),
], ids=["omitted", "on-split", "on-equals", "off-split", "off-equals"])
def test_progress_cli_context_delivery_overrides(
tmp_path: Path, monkeypatch: pytest.MonkeyPatch, provider: str,
context_args: tuple[str, ...], navigation: bool,
) -> None:
tmp_path = tmp_path.resolve()
isolate_sqlite_runtime(tmp_path, monkeypatch)
monkeypatch.setenv("LOOPX_CONTEXT_DELIVERY", "on")
native = tmp_path / "native"
native.mkdir(mode=0o700)
captures = tmp_path / "captures"
captures.mkdir(mode=0o700)
fixture = make_progress_cli_fixture(tmp_path, provider, "advanced")
try:
result = call_progress_cli(
fixture, "quota", "should-run", "--codex-app", "--goal-id", GOAL,
"--agent-id", AGENT, "--turn-instance-id", TURN,
"--codex-context-dir", str(native),
"--decision-output-root", str(captures), *context_args,
)
assert (result.get("schema_version") == "context_capture_navigation_v1") is navigation
if not navigation:
assert result["decision"] == "autonomous_replan_required", result
finally:
restart_effect_runtime(wait_for_exit=True)


def _authority(fixture: dict) -> dict:
result = read_canonical_snapshot(rpc=effect_runtime_result, runtime_root=str(fixture["runtime"]),
goal_id=GOAL, include_leases=True, projection_readback=None, timeout=20)
Expand Down
Loading