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
10 changes: 10 additions & 0 deletions docs/reference/required-work-context.md
Original file line number Diff line number Diff line change
Expand Up @@ -856,6 +856,12 @@ known pointer does not require another index round trip. Batch within the combin
output budget, avoid overlapping parent/child selections, and inspect a missing
pointer's parent before retrying the rejected batch. These are caller guidelines;
selection validation, required reads and authority checks remain unchanged.
When it fits the existing native-reference output ceiling, `field_index` supplies
the complete top-level index of the current recovery capture. Its pointers,
types, byte sizes and member counts match `context-read --list`; it contains no
field bodies and never proves they were read. Select those pointers through
`recovery.command`; a delta's `command` still addresses its patch. Oversized
indexes are omitted whole, leaving `index_command` and full recovery available.
Selection errors identify the original `--select` argument and, for a failed
lookup, its token position (both 1-based). Sorting and duplicate elimination do
not renumber arguments. Inspect the resolved prefix before that token in the
Expand Down Expand Up @@ -896,6 +902,10 @@ pointer 从原始摘要绑定的 capture 批量读取详情。提供已有 `--ca
发现多层字段。深度默认为 1,可选 1–8;需要更深时选择新的父节点继续。这只限制
单次遍历深度,不限制 capture 容量或可读正文。优先展开相关子树,省略路径才从根开始。
生成的读取指引会提示上述选择,不把查目录变成前置步骤,也不改变工作前的必读要求。
在原生引用的现有输出上限允许时,`field_index` 直接提供当前 recovery capture 的完整
顶层目录,其 pointer、类型、字节数和成员数与 `context-read --list` 一致。目录不含
正文,也不证明已阅读;通过 `recovery.command` 选读这些路径,delta 的 `command`
仍指向补丁。过大目录整体省略,保留 `index_command` 与完整恢复路径。
普通 capture 回复、原生持久配置与压缩后恢复携带同一份选择指引。恢复命令直接指向
`--select`,已知路径无须多查一轮目录。按合计输出预算分批,避免同时选择父节点和
子节点;路径缺失时先查其父节点,再重试被拒绝的批次。这些是调用建议,不改变
Expand Down
51 changes: 37 additions & 14 deletions loopx/cli_commands/quota_capture.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,24 @@ def fits(result: dict[str, Any]) -> bool:
return best


def _context_index_fields(payload: dict[str, Any], children: list[dict[str, Any]]) -> list[dict[str, Any]]:
"""Serialize metadata for TS-verified addresses, preserving Python JSON values."""
fields = []
for child in children:
value: Any = payload
for key in child["path"]:
value = value[key]
field = {"pointer": child["pointer"], "type":
"object" if isinstance(value, dict) else "array" if isinstance(value, list)
else "null" if value is None else "boolean" if isinstance(value, bool)
else "string" if isinstance(value, str) else "number",
"bytes": len(json.dumps(value, ensure_ascii=False, separators=(",", ":")).encode("utf-8"))}
if isinstance(value, (dict, list)):
field["count"] = len(value)
fields.append(field)
return fields


def read_context_capture(args: argparse.Namespace, *, presentation: dict[str, Any] | None = None,
next_page_bytes: int | None = None,
next_page_output_bytes: int | None = None) -> dict[str, Any]:
Expand Down Expand Up @@ -163,20 +181,7 @@ def read_context_capture(args: argparse.Namespace, *, presentation: dict[str, An
for key in item["path"]:
selected = selected[key]
if list_fields:
fields = []
for child in item["children"]:
value = payload
for key in child["path"]:
value = value[key]
field = {"pointer": child["pointer"], "type":
"object" if isinstance(value, dict) else "array" if isinstance(value, list)
else "null" if value is None else "boolean" if isinstance(value, bool)
else "string" if isinstance(value, str) else "number",
"bytes": len(json.dumps(value, ensure_ascii=False, separators=(",", ":")).encode("utf-8"))}
if isinstance(value, (dict, list)):
field["count"] = len(value)
fields.append(field)
views.append({"pointer": item["pointer"], "fields": fields})
views.append({"pointer": item["pointer"], "fields": _context_index_fields(payload, item["children"])})
else:
views.append({"pointer": item["pointer"], "value": selected})
view_options = {"list_depth": list_depth} if list_depth is not None and list_depth != 1 else {}
Expand Down Expand Up @@ -273,6 +278,24 @@ def native_context_capture_view(projected: dict[str, Any], directory: Path, *,
# The reference must fit even under an explicit small caller ceiling.
def fits():
return len(json.dumps(result, ensure_ascii=False, separators=(",", ":")).encode()) + 1 <= min(output_bytes, 7900)
# The same complete top-level index as `context-read --list`, bound to
# recovery (current facts), not a delta's patch keys. This saves an index
# tool roundtrip when it fits; it neither supplies source contents nor
# acknowledges their delivery. Deeper navigation keeps its existing route.
from ..control_plane.quota.turn_envelope import _turn_envelope_result

# Depth-one addressing needs keys only, not another transport of every
# source body. Metadata bytes/types are read from the original JSON below.
try:
plan = _turn_envelope_result("context_select", context=dict.fromkeys(current_document), select=[""], list_fields=True)
except (EffectRuntimeRemoteError, EffectRuntimeStartupError):
# An optional index cannot turn a valid immutable file reference into
# a failed delivery. Ordinary full recovery remains a file-only read.
pass
else:
result["field_index"] = _context_index_fields(current_document, plan["selections"][0]["children"])
if not fits():
result.pop("field_index") # Optional metadata must never displace recovery or instructions.
if not fits():
result.pop("overview")
if not fits():
Expand Down
2 changes: 2 additions & 0 deletions tests/control_plane/test_codex_context_lifecycle.py
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,8 @@ def test_native_reference_exposes_file_continuity_and_preserves_full_recovery(tm
assert view["continuity_basis"] == "captured_file"
assert view["baseline_reference"]["path"] == first["recovery"]["path"]
assert view["recovery"]["path"] == second["recovery"]["path"]
assert [field["pointer"] for field in view["field_index"]] == list("/" + key for key in payload)
assert "/changes" not in [field["pointer"] for field in view["field_index"]], "index addresses current recovery, never the delta wire"
for instruction in (view["instruction"], second["recovery"]["instruction"]):
assert "Native input observation independently verifies" not in instruction
deliver(tmp_path, event, capture_pages(view["path"], view["sha256"]))
Expand Down
51 changes: 51 additions & 0 deletions tests/control_plane/test_context_capture_selection.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import hashlib
import json
import shlex
from pathlib import Path

import pytest

Expand Down Expand Up @@ -50,6 +51,56 @@ def args(path, raw):
offset=0, page_bytes=256, max_page_output_bytes=2000, format="json", select=["/rows/0"]))


def test_native_reference_reuses_the_exact_index_before_selecting_details(tmp_path):
from loopx.cli import build_parser
from loopx.cli_commands.quota_capture import native_context_capture_view

original = {"requirements": {"text": "Preserve acceptance and stop conditions. " * 100},
"a/b~": [None, True, 9007199254740993], "nullable": None}
reference = native_context_capture_view(original, tmp_path)
parser = build_parser()
indexed = read_context_capture(parser.parse_args(shlex.split(reference["index_command"])[1:]))
assert indexed["ok"] and indexed["eof"]
assert reference["field_index"] == json.loads(indexed["content"])["selections"][0]["fields"]
assert [item["pointer"] for item in reference["field_index"]] == ["/requirements", "/a~1b~0", "/nullable"]
assert "Preserve acceptance" not in json.dumps(reference)
assert "content" not in reference and "eof" not in reference
assert capture_page_range(reference, raw=b"", digest=reference["sha256"]) is None
# The inline index replaces only discovery, never the content read.
selected = read_context_capture(parser.parse_args(shlex.split(reference["recovery"]["command"])[1:]
+ ["--select", "/a~1b~0"]))
assert selected["ok"]
assert json.loads(selected["content"])["selections"][0]["value"] == original["a/b~"]


def test_large_inline_index_is_omitted_whole_without_displacing_navigation(tmp_path):
from loopx.cli_commands.quota_capture import native_context_capture_view

original = {"field-" + str(index): {"preserve": index} for index in range(300)}
reference = native_context_capture_view(original, tmp_path)
assert "field_index" not in reference
assert "recovery" in reference and "index_command" in reference and "select_command" in reference
assert len(json.dumps(reference, ensure_ascii=False, separators=(",", ":")).encode()) + 1 <= 7900
assert json.loads(Path(reference["recovery"]["path"]).read_text()) == original


def test_unavailable_optional_index_keeps_file_only_recovery(tmp_path, monkeypatch):
from loopx.cli import build_parser
from loopx.cli_commands.quota_capture import native_context_capture_view
from loopx.control_plane.effect_runtime import EffectRuntimeStartupError
from loopx.control_plane.quota import turn_envelope

def unavailable(*args, **kwargs):
raise EffectRuntimeStartupError("Synthetic typed runtime unavailable", diagnostic_code="fixture_unavailable")

monkeypatch.setattr(turn_envelope, "_turn_envelope_result", unavailable)
original = {"requirements": "Keep every requirement and stop condition."}
reference = native_context_capture_view(original, tmp_path)
assert reference["ok"] and "field_index" not in reference
page = read_context_capture(build_parser().parse_args(shlex.split(reference["recovery"]["command"])[1:]))
assert page["ok"] and json.loads(page["content"]) == original


def test_native_reference_reader_uses_real_pages_before_recording_delivery(tmp_path):
path, raw, _ = fixture_capture(tmp_path)
options = args(path, raw)
Expand Down
Loading