Files
openclaw/src/agents/session-runtime-compat.ts
Peter Steinberger f94a7dc183 feat(codex): supervise native Codex sessions (#104045)
* feat(codex): add native session supervision

* fix(codex): harden supervision integration

* fix(codex): preserve locked harness ownership

* fix(codex): fence native session archive

* fix(codex): revalidate archive binding ownership

* feat(codex): integrate supervision runtime

* feat(sessions): preserve harness-owned execution

* feat(sessions): persist harness ownership invariants

* feat(gateway): enforce harness-owned sessions

* feat(setup): enable detected Codex supervision

* feat(mac): expose supervised Codex sessions

* feat(ui): make Codex sessions actionable

* docs(codex): document session supervision

* test(codex): cover integration ownership

* chore(i18n): refresh supervision inventories

* fix(setup): finalize Codex activation atomically

* test(codex): narrow binding store update

* fix(sessions): preserve legacy model locks

* test(macos): serialize Codex catalog fixtures

* fix(sessions): preserve legacy lock admission

* chore(i18n): reconcile supervision metadata

* test(sessions): mark legacy lock fixture

* fix(macos): drain final Codex catalog frame

* docs: leave supervision note to release

* style(macos): satisfy Codex catalog type length

* chore: record session accessor seam owners

* fix(macos): honor configured Codex supervision

* fix(codex): preserve harness-owned model locks

* fix(codex): satisfy supervision lint gates

* chore(i18n): refresh native supervision inventory

* fix(codex): align supervision validation contracts

* fix(codex): close supervision boundary gaps

* fix(codex): preserve supervision activation contracts

* fix(codex): dispose standalone supervision runtime

* fix(codex): pin supervised source connection

* fix(plugins): bind delegated runs to exact session target

* fix(codex): scope supervised sessions to configured agents

* fix(codex): fingerprint effective supervision home

* fix(codex): normalize supervision plugin policy

* fix(codex): keep supervised bindings stable across upgrades

* fix(codex): guard all supervised binding connections

* fix(codex): preserve catalog filters and pending CAS identity

* fix(codex): preserve supervision identity for diagnostics

* fix(codex): bind uncertain commits to supervision connection

* fix(codex): satisfy supervision type boundaries

* fix(macos): reconcile current main validation

* fix(codex): handle absent runtime config in supervision

* fix(doctor): own local audio acceleration check

* fix(codex): satisfy integration lint gates

* fix(codex): satisfy lifecycle safety guards
2026-07-11 00:12:08 -07:00

85 lines
3.2 KiB
TypeScript

/**
* Session runtime compatibility helpers.
*
* Resolves persisted runtime overrides without leaking provider-specific CLI runtime bindings across model routes.
*/
import type { SessionEntry } from "../config/sessions.js";
import type { OpenClawConfig } from "../config/types.openclaw.js";
import { isDefaultAgentRuntimeId } from "./agent-runtime-id.js";
import { normalizeOptionalAgentRuntimeId } from "./agent-runtime-id.js";
import { isCliRuntimeAliasForProvider } from "./model-runtime-aliases.js";
/** Persisted runtime fields used to recover session runtime compatibility. */
type SessionRuntimeCompatEntry = Pick<
SessionEntry,
"agentHarnessId" | "agentRuntimeOverride" | "modelSelectionLocked"
>;
type SessionRuntimeOverrideEntry = Pick<
SessionEntry,
"agentHarnessId" | "agentRuntimeOverride" | "modelSelectionLocked"
>;
/** Resolves the persisted runtime id, preserving locked transcript ownership. */
export function resolvePersistedSessionRuntimeId(
entry?: SessionRuntimeCompatEntry,
): string | undefined {
const harnessRuntime = normalizeOptionalAgentRuntimeId(entry?.agentHarnessId);
if (
entry?.modelSelectionLocked === true &&
harnessRuntime &&
!isDefaultAgentRuntimeId(harnessRuntime)
) {
return harnessRuntime;
}
const runtimeOverride = normalizeOptionalAgentRuntimeId(entry?.agentRuntimeOverride);
if (runtimeOverride && !isDefaultAgentRuntimeId(runtimeOverride)) {
return runtimeOverride;
}
return harnessRuntime;
}
/** Resolves a runtime id only when it can serve the selected provider. */
export function resolveCompatibleAgentRuntimeForProvider(params: {
provider?: string | null;
runtime?: string | null;
cfg?: OpenClawConfig;
}): string | undefined {
const runtime = normalizeOptionalAgentRuntimeId(params.runtime);
if (!runtime || isDefaultAgentRuntimeId(runtime)) {
return undefined;
}
if (runtime === "openclaw") {
return runtime;
}
const provider = params.provider?.trim().toLowerCase() ?? "";
// The Codex harness owns both OpenClaw's virtual Codex namespace and canonical OpenAI routes.
if (runtime === "codex" && (provider === "codex" || provider === "openai")) {
return runtime;
}
return isCliRuntimeAliasForProvider({ provider, runtime, cfg: params.cfg }) ? runtime : undefined;
}
/** Resolves a persisted runtime override only when it can serve the selected provider. */
export function resolveSessionRuntimeOverrideForProvider(params: {
provider?: string | null;
entry?: SessionRuntimeOverrideEntry;
cfg?: OpenClawConfig;
}): string | undefined {
const lockedHarness = normalizeOptionalAgentRuntimeId(params.entry?.agentHarnessId);
if (
params.entry?.modelSelectionLocked === true &&
lockedHarness &&
!isDefaultAgentRuntimeId(lockedHarness)
) {
// A locked transcript stays with its creating harness; provider metadata on
// internal turns must not reinterpret that runtime as a CLI backend.
return lockedHarness;
}
// agentHarnessId records the runtime that produced the existing transcript;
// it must not override the runtime selected for the next turn.
return resolveCompatibleAgentRuntimeForProvider({
provider: params.provider,
runtime: params.entry?.agentRuntimeOverride,
cfg: params.cfg,
});
}