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
13 changes: 12 additions & 1 deletion docs/reference/required-work-context.md
Original file line number Diff line number Diff line change
Expand Up @@ -435,7 +435,14 @@ output profile. Both the initial guard and continuations use that page budget,
including when the shell lacks the declaration. The worker applies this configuration
automatically inside its isolated opt-in trial. The persistent instruction requests
22000 tokens for each context-read tool result and 24000 for its code-mode emission,
forwarding one stdout at a time. Remove the generated output overrides together with the
forwarding one stdout at a time. The post-compaction/recovery hook carries the same
per-call budget guidance so recovery does not depend on retaining the setup text.
Both the nested reader and outer code-mode emission can truncate independently;
per-call requests do not prove retained history or change host configuration.
If either layer truncates, retry the affected range of the same capture with
smaller content and complete-output byte budgets. This avoids a transport retry
failure; it does not make an oversized total context fit or qualify scoped reads.
Remove the generated output overrides together with the
context setup on rollback; saving a machine preference alone does not apply them.
This output sizing does not prove retained input, lower fees or task benefit.
For an SSH Goal, replace `--codex-app`
Expand Down Expand Up @@ -677,6 +684,10 @@ exec stdout;把整包重打进哈希工具不构成原始字节已被保留的
开启的 benchmark worker 在其
隔离会话内自动应用;持久指引要求每次续读直接输出预算 22000 token、Code Mode
输出预算 24000 token,每次直接转发一份 stdout。
压缩/恢复 hook 同样携带这段调用预算指引,避免恢复依赖已经丢失的配置正文。
内层读取与外层 Code Mode 输出可分别截断;单次预算请求不证明历史保留,也不修改宿主配置。
任一层截断时,减小正文和完整输出字节预算,重读同一 capture 的受影响范围。
这仅修复传输重试故障,不代表超大的完整上下文已能容纳,也不证明范围裁剪合格。
回滚时同时移除生成的输出覆盖项;仅保存机器偏好并不会应用这些宿主配置。
该设置不证明输入保留、总费用降低或任务效果改善。
读取器校验不可变 capture 的摘要。Post-tool 适配层复用显式输入观察的字节范围校验,
Expand Down
12 changes: 10 additions & 2 deletions loopx/control_plane/turn_driver/codex_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,13 @@ def _context_continuation_instructions(command: str) -> str:
)


# Both persistent setup and post-compaction recovery must describe the nested
# output budgets. The hook may be the only instruction retained after loss.
_NATIVE_CONTEXT_OUTPUT_GUIDANCE = (
"For 64000-byte pages request reader max_output_tokens=22000 and code-mode exec pragma max_output_tokens=24000. "
)


def codex_context_recovery_instructions(directory: str, *, goal_id: str, agent_id: str,
cli_argv: list[str], session_root: bool = False,
page_output_bytes: int = NATIVE_CONTEXT_PAGE_OUTPUT_BYTES) -> str:
Expand All @@ -239,8 +246,8 @@ def codex_context_recovery_instructions(directory: str, *, goal_id: str, agent_i
_context_continuation_instructions(command) +
"When recovering a required full read, follow next_command through eof and verify complete bytes/digest. " +
("The generated native configuration supports 64000-byte context-read outputs and a 20000-token history limit. "
"Read one continuation per tool call with max_output_tokens=22000. In code-mode, also set the exec "
"pragma max_output_tokens to 24000 and forward successful stdout directly with text(result.output). "
+ _NATIVE_CONTEXT_OUTPUT_GUIDANCE +
"Read one continuation per tool call; in code-mode, forward successful stdout directly with text(result.output). "
if page_output_bytes == NATIVE_CONTEXT_LARGE_OUTPUT_BYTES else "") +
"For code-mode reads, size batches against both direct-result and retained-history output limits; "
"max_output_tokens alone does not establish the latter. Read one output at a time with "
Expand Down Expand Up @@ -342,6 +349,7 @@ def codex_context_hook(directory: str | None, event: dict[str, Any]) -> dict[str
return {"hookSpecificOutput": {"hookEventName": name, "additionalContext":
"LoopX context baseline invalidated. "
+ _context_continuation_instructions(recovery["command"])
+ _NATIVE_CONTEXT_OUTPUT_GUIDANCE
+ "When completing a required full-capture read: " + CONTEXT_CAPTURE_PAGE_GUIDANCE}}
return {}

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 @@ -76,6 +76,7 @@ def test_native_configuration_cli_is_read_only_and_usable_without_registry(tmp_p
"shell_environment_policy.set.LOOPX_CONTEXT_PAGE_OUTPUT_BYTES": "64000"}
assert "--max-page-output-bytes 64000" in native["developer_instructions"]
assert "max_output_tokens=22000" in native["developer_instructions"]
assert "max_output_tokens=24000" in native["developer_instructions"]
assert "hooks.state" not in native and list(tmp_path.iterdir()) == []
missing_identity = subprocess.run(command[:-2], cwd=tmp_path,
env={**os.environ, "PYTHONPATH": str(repo)}, capture_output=True, text=True, timeout=15)
Expand Down Expand Up @@ -119,6 +120,7 @@ def test_lifecycle_invalidates_and_recovers_current_capture_without_bodies(tmp_p
assert first["recovery"]["sha256"] in body and "quota context-read" in body
# The additional work-Turn/read-obligation distinction is intentional;
# this synthetic allowance is not a host output or context limit.
assert "max_output_tokens=22000" in body and "max_output_tokens=24000" in body
assert payload["requirements"] not in body and len(body) < 2300
else:
assert result == {}
Expand Down
11 changes: 10 additions & 1 deletion tests/control_plane/test_codex_context_resume.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,10 @@ def test_compact_full_recovery_becomes_next_resume_baseline(tmp_path, monkeypatc
assert invalid["context_epoch"] != before["context_epoch"]
assert invalid["recovery"] == before["recovery"]
assert invalid["recovery"]["command"] in str(recovery_instruction)
guidance = recovery_instruction["hookSpecificOutput"]["additionalContext"]
assert "max_output_tokens=22000" in guidance
assert "max_output_tokens=24000" in guidance
assert "grants no new authority/freshness" in guidance and "retention proof" in guidance

reference = invalid["recovery"]
offset, index = 0, 0
Expand Down Expand Up @@ -254,7 +258,12 @@ def hook(values):
assert "candidate" not in after and "pending" not in after
assert after["context_epoch"] != before["context_epoch"]
assert after["recovery"] == reference
assert reference["command"] in result["hookSpecificOutput"]["additionalContext"]
guidance = result["hookSpecificOutput"]["additionalContext"]
assert reference["command"] in guidance
# Actual CLI hook recovery must stand alone after persistent context loss.
assert "max_output_tokens=22000" in guidance
assert "max_output_tokens=24000" in guidance
assert "grants no new authority/freshness" in guidance and "retention proof" in guidance
_, fallback = project(tmp_path, "after-fifo", payload=payload)
assert fallback["mode"] == "full" and fallback["context"] == payload
assert Path(reference["path"]).read_bytes() == captured
Expand Down
Loading