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 @@ -12,6 +12,7 @@ type FieldCopy = Record<string, Readonly<{ description?: string; label: string;

const capabilityCopy: Record<WorkspaceLocale, Record<string, LocalizedCopy>> = {
en: {
context_delivery: {displayName: "Differential context", description: "Reuse unchanged context across supported Agent turns. A missing retained baseline keeps the full context."},
codex_chat: {displayName: "Codex Goal conversation defaults", description: "Choose the native Codex profile, model, speed tier and reasoning effort for new Goal conversations. Existing conversations keep their original history. This does not start or reconfigure an active Agent Loop, worker or steward."},
decision_context: {displayName: "Find evidence", description: "Find advisory evidence with a temporary private profile. OpenViking and BM25 are retrieval implementations; this page does not save a binding or enable automatic memory."},
content_ops: {displayName: "Content production", description: "Prepare source-backed outlines, compose local videos or generate cloud images and footage with the optional media provider. Review the result before sharing."},
Expand Down Expand Up @@ -81,6 +82,7 @@ const capabilityCopy: Record<WorkspaceLocale, Record<string, LocalizedCopy>> = {
},
},
"zh-CN": {
context_delivery: {displayName: "差分上下文", description: "在支持的 Agent 轮次间复用未变化的上下文;无法确认基线保留时使用完整上下文。"},
codex_chat: {displayName: "Codex Goal 对话默认值", description: "分别选择 Codex 配置来源、模型、速度档和推理强度,作用于本机的新 Goal 对话。已有对话保留原历史;不会启动或重配正在运行的 Agent Loop、工作 Agent 或管家。"},
decision_context: {displayName: "资料召回", description: "通过临时私有配置查找参考证据。OpenViking、BM25 是检索实现;本页不保存绑定,也不启用自动记忆。"},
content_ops: {displayName: "内容制作", description: "准备有来源的提纲,使用可选媒体扩展制作本机视频、生成云端图像与镜头,检查作品后再分享。"},
Expand Down Expand Up @@ -244,6 +246,11 @@ export function localizeCapability(
}

export function localizedCapabilityFieldCopy(locale: WorkspaceLocale, capabilityId?: string): FieldCopy {
if (capabilityId === "context_delivery") return {...fieldCopy[locale], mode: locale === "zh-CN" ? {
label: "Codex", description: "仅作用于支持的 Codex 心跳;显式关闭的实验保持关闭。", options: {off: "关闭", on: "开启"},
} : {
label: "Codex", description: "Applies only to supported Codex heartbeats; explicitly disabled runs stay disabled.", options: {off: "Off", on: "On"},
}};
if (capabilityId === "codex_chat") return {...fieldCopy[locale], ...(locale === "zh-CN" ? {
codex_profile: {label: "Codex 配置来源", description: "选择已有本机配置,例如 codex-gpt。账户和凭据留在原目录,不复制;留空继承服务配置。"},
model: {label: "对话模型", description: "例如 gpt-6.1-sol;留空继承所选 Codex 配置的模型。"},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,26 @@ export function MachineConfigurationSettings({ section, onChanged }: {
setError(null);
}

async function setContextDelivery(mode: "off" | "on") {
if (busy || !editorAvailable || selected?.capability_id !== "context_delivery" || !selected.machine_namespace) return;
const namespace = selected.machine_namespace;
const configuration = {...selected.default, mode};
setBusy("apply"); setError(null); setNotice(null);
try {
const plan = await previewMachineConfiguration(namespace, configuration);
await applyMachineConfiguration(namespace, configuration, plan.plan_revision);
const next = await fetchMachineConfiguration();
setInspection(next);
if (next.machine_configuration?.namespaces[namespace]?.mode !== mode) {
throw new Error(locale === "zh-CN" ? "保存后的配置已变化,请刷新后重试。" : "The saved configuration changed. Refresh and retry.");
}
setNotice(locale === "zh-CN" ? "Codex 偏好已保存。" : "Codex preference saved.");
onChanged?.();
} catch (cause) {
setError(cause instanceof Error ? cause.message : t("machine.applyError"));
} finally { setBusy(null); }
}

async function createPreview() {
if (!editorAvailable || !selected?.machine_namespace || !desiredConfiguration || !editorValid || busy) return;
setBusy("preview");
Expand Down Expand Up @@ -438,7 +458,21 @@ export function MachineConfigurationSettings({ section, onChanged }: {
</section>
) : null}

{editorAvailable ? <>{editorMode === "json" || !selected.configuration_editor.fields.some((field) => field.key === "enabled" && field.input_kind === "boolean") ? <div className="personal-capability-editor-mode">
{selected.capability_id === "context_delivery" ? <section aria-label={locale === "zh-CN" ? "使用差分上下文的应用" : "Applications using differential context"} className="personal-capability-field-summary">
<div className="personal-capability-fields"><label className="is-boolean">
<span>Codex</span>
<input aria-label={locale === "zh-CN" ? "在 Codex 中使用差分上下文" : "Use differential context in Codex"}
type="checkbox" role="switch" checked={selectedCurrent?.mode === "on"} disabled={Boolean(busy) || !editorAvailable}
onChange={(event) => void setContextDelivery(event.target.checked ? "on" : "off")} />
</label></div>
<p role="status">{selectedCurrent?.mode === "on"
? locale === "zh-CN" ? "已为 Codex 保存开启偏好;宿主就绪与实际使用尚未验证。" : "Codex preference is on; host readiness and actual use are not verified."
: locale === "zh-CN" ? "Codex 未开启。" : "Off for Codex."}</p>
<ContextHelp label={locale === "zh-CN" ? "Codex 支持范围与生效条件" : "Codex support and activation requirements"}><p>{locale === "zh-CN"
? "目前仅支持 Codex App 心跳和 benchmark 心跳,无法确认或不支持的跑法报错。保存偏好不代表当前会话已采用差分,也不会改变其他应用或显式关闭的实验。宿主准备就绪且旧上下文完整时才使用差分,否则保留完整上下文。私有存储与会话隔离自动管理;每轮回执显示实际传输方式。"
: "Currently supports only Codex App and benchmark heartbeats; unknown or unsupported declarations return an error. Saving a preference does not establish use in the current session or change other applications or explicitly disabled runs. Delta requires a ready host and complete retained context; otherwise full context is preserved. Private storage and session isolation are automatic; each delivery reports its actual mode."}</p></ContextHelp>
</section> : null}
{editorAvailable && selected.capability_id !== "context_delivery" ? <>{editorMode === "json" || !selected.configuration_editor.fields.some((field) => field.key === "enabled" && field.input_kind === "boolean") ? <div className="personal-capability-editor-mode">
<button onClick={() => changeMode(editorMode === "guided" ? "json" : "guided")} type="button">
<Code2 aria-hidden size={14} />{t(editorMode === "guided" ? "machine.editJson" : "machine.backToForm")}
</button>
Expand Down Expand Up @@ -487,7 +521,7 @@ export function MachineConfigurationSettings({ section, onChanged }: {
</section>
) : null}

{editorAvailable ? <footer className="personal-capability-actions">
{editorAvailable && selected.capability_id !== "context_delivery" ? <footer className="personal-capability-actions">
{configured ? <button className="is-danger" disabled={Boolean(busy)} onClick={() => void createRemovalPreview()} type="button"><Trash2 aria-hidden size={15} />{t("machine.previewRemoval")}</button> : null}
<button disabled={Boolean(busy) || !editorValid} onClick={() => void createPreview()} type="button">{busy === "preview" ? t("common.loading") : t("machine.previewChanges")}</button>
<button className="is-primary" disabled={Boolean(busy) || !preview} onClick={() => void applyPreview()} type="button">{busy === "apply" ? t("common.loading") : t("machine.applyPreview")}</button>
Expand Down
3 changes: 2 additions & 1 deletion benchmark/runtime/context_delivery.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ def preflight_context_instruction(env: dict[str, str], path: Path, digest: str,
"--turn-instance-id", turn_id, "--context-delivery", "on", "--runtime-profile", "generic_cli", "--codex-context-dir", env["LOOPX_CODEX_CONTEXT_DIR"]]
full = [*prefix, "context-read", *source]
return ("Present that same immutable packet with:\n```sh\n" + shlex.join(project)
+ "\n```\nFollow the returned command and all next_command pages; reconstruct any delta against "
+ "\n```\nConsume any returned page content, then follow next_command through eof. "
"If no page content is returned, run command and follow all next_command pages. Reconstruct any delta against "
"its exact retained baseline before following the original interaction_contract. "
"If projection is unavailable, the baseline is absent/uncertain, or a response is incomplete, "
"follow its full recovery reference. If the projection command itself fails, read the original "
Expand Down
3 changes: 3 additions & 0 deletions benchmark/runtime/worker.py
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,9 @@ def run_once(env: dict[str, str]) -> dict:
wake.mkdir(parents=True, exist_ok=False)
home = Path(env["LOOPX_CODEX_HOME"])
env = process_environment(home, base=env)
# Preserve this trial's resolved off/on choice in both preflight and solver
# subprocesses; an omitted off must not inherit a machine-wide opt-in.
env["LOOPX_CONTEXT_DELIVERY"] = execution.context_delivery
# Internal transport arguments are derived afresh, never ambient authority.
env.pop("LOOPX_CODEX_CONTEXT_DIR", None)
env.pop("LOOPX_CODEX_CONTEXT_TRUST_ARGS", None)
Expand Down
12 changes: 6 additions & 6 deletions docs/heartbeat-automation-prompt.md
Original file line number Diff line number Diff line change
Expand Up @@ -455,15 +455,16 @@ Generic CLI, visible native Goals, Claude and other hosts remain outside this
opt-in. Harbor/container and installed desktop adoption retain their separate
unqualified boundaries; listing an entry does not certify live adoption.

For a trusted Codex host, create private context/capture directories and render
the native setup through the installed CLI:
For a trusted Codex host, render the native setup through the installed CLI.
Private context/capture directories are selected and created automatically under
the resolved machine runtime; advanced callers may override those locations:

```sh
loopx --format json quota context-config --context-delivery on --codex-app \
--codex-context-root <private-context-root> --goal-id <goal> --agent-id <agent>
--goal-id <goal> --agent-id <agent>
```

The read-only result contains `native_config.hooks` and
The result contains `native_config.hooks` and
`native_config.developer_instructions`. Merge the hooks into the host's existing
`hooks.json` or inline hook configuration, and append the recovery instruction to
its existing developer instructions. Preserve other configuration. Review and
Expand All @@ -474,8 +475,7 @@ different native sessions in separate journals, including interleaved sessions.

Generate the normal bootstrap with `heartbeat-prompt --thin --codex-app
--bootstrap`, its existing Goal/Agent/registry arguments, and
`--context-delivery on --decision-output-root <private-capture-root> --codex-context-root
<private-context-root>`; optionally add `--turn-envelope`. The loader preserves
`--context-delivery on`; optionally add `--turn-envelope` or explicit private paths. The loader preserves
these options without freezing a Turn ID. Each wake loads current instructions
and binds the existing `LOOPX_TURN` before its generated guard. Selection keeps
the same transport. An unset wake identity fails in the shell before admission.
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/reference/assets/context-one-switch-on.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading