Vendor OpenClaw source as Adolf fork baseline
Some checks failed
ClawSweeper Dispatch / dispatch (push) Has been cancelled
CodeQL / Security High (actions) (push) Has been cancelled
CodeQL / Security High (channel-runtime-boundary) (push) Has been cancelled
CodeQL / Security High (core-auth-secrets) (push) Has been cancelled
CodeQL / Security High (mcp-process-tool-boundary) (push) Has been cancelled
CodeQL / Security High (network-ssrf-boundary) (push) Has been cancelled
CodeQL / Security High (plugin-trust-boundary) (push) Has been cancelled
CodeQL / Security High (process-exec-boundary) (push) Has been cancelled
Docs Sync Publish Repo / sync-publish-repo (push) Has been cancelled
Docs / docs (push) Has been cancelled
OpenClaw Stable Main Closeout / Resolve stable release closeout inputs (push) Has been cancelled
OpenClaw Stable Main Closeout / Verify stable main closeout (push) Has been cancelled
Workflow Sanity / no-tabs (push) Has been cancelled
Workflow Sanity / actionlint (push) Has been cancelled
Workflow Sanity / generated-doc-baselines (push) Has been cancelled
CI / runner-admission (push) Has been cancelled
CI / preflight (push) Has been cancelled
CI / security-fast (push) Has been cancelled
CI / pnpm-store-warmup (push) Has been cancelled
CI / build-artifacts (push) Has been cancelled
CI / native-i18n (push) Has been cancelled
CI / ${{ matrix.check_name }} (push) Has been cancelled
CI / ${{ matrix.checkName }} (push) Has been cancelled
CI / checks-node-compat-node22 (push) Has been cancelled
CI / check-bundled-channel-config-metadata (push) Has been cancelled
CI / check-dependencies (push) Has been cancelled
CI / check-guards (push) Has been cancelled
CI / check-lint (push) Has been cancelled
CI / check-prod-types (push) Has been cancelled
CI / check-shrinkwrap (push) Has been cancelled
CI / check-test-types (push) Has been cancelled
CI / check-additional-boundaries-a (push) Has been cancelled
CI / check-additional-boundaries-bcd (push) Has been cancelled
CI / check-additional-extension-bundled (push) Has been cancelled
CI / check-additional-extension-channels (push) Has been cancelled
CI / check-additional-extension-package-boundary (push) Has been cancelled
CI / check-additional-runtime-topology-architecture (push) Has been cancelled
CI / check-session-accessor-boundary (push) Has been cancelled
CI / check-session-transcript-reader-boundary (push) Has been cancelled
CI / check-docs (push) Has been cancelled
CI / skills-python (push) Has been cancelled
CI / macos-swift (push) Has been cancelled
CI / ios-build (push) Has been cancelled
CI / ci-timings-summary (push) Has been cancelled
Native App Locale Refresh / Refresh native fa (push) Has been cancelled
Native App Locale Refresh / Refresh native fr (push) Has been cancelled
Native App Locale Refresh / Refresh native hi (push) Has been cancelled
Native App Locale Refresh / Refresh native id (push) Has been cancelled
Native App Locale Refresh / Refresh native it (push) Has been cancelled
Native App Locale Refresh / Refresh native ja-JP (push) Has been cancelled
Control UI Locale Refresh / plan (push) Has been cancelled
Control UI Locale Refresh / Refresh ${{ matrix.locale }} (push) Has been cancelled
Control UI Locale Refresh / Commit control UI locale refresh (push) Has been cancelled
Live Media Runner Image / Build live media runner image (push) Has been cancelled
Native App Locale Refresh / Refresh native ar (push) Has been cancelled
Native App Locale Refresh / Refresh native de (push) Has been cancelled
Native App Locale Refresh / Refresh native es (push) Has been cancelled
Native App Locale Refresh / Refresh native ko (push) Has been cancelled
Native App Locale Refresh / Refresh native nl (push) Has been cancelled
Native App Locale Refresh / Refresh native pl (push) Has been cancelled
Native App Locale Refresh / Refresh native pt-BR (push) Has been cancelled
Native App Locale Refresh / Refresh native ru (push) Has been cancelled
Native App Locale Refresh / Refresh native sv (push) Has been cancelled
Native App Locale Refresh / Refresh native th (push) Has been cancelled
Native App Locale Refresh / Refresh native tr (push) Has been cancelled
Native App Locale Refresh / Refresh native uk (push) Has been cancelled
Native App Locale Refresh / Refresh native vi (push) Has been cancelled
Native App Locale Refresh / Refresh native zh-CN (push) Has been cancelled
Native App Locale Refresh / Refresh native zh-TW (push) Has been cancelled
Native App Locale Refresh / Commit native locale refresh (push) Has been cancelled
Plugin Init Scaffold Validation / Validate provider scaffold (push) Has been cancelled
Plugin NPM Release / preview_plugins_npm (push) Has been cancelled
Plugin NPM Release / Validate release publish approval (push) Has been cancelled
Plugin NPM Release / preview_plugin_pack (push) Has been cancelled
Plugin NPM Release / publish_plugins_npm (push) Has been cancelled
Sandbox Common Smoke / sandbox-common-smoke (push) Has been cancelled
Website Installer Sync / static (push) Has been cancelled
Website Installer Sync / linux-docker (push) Has been cancelled
Website Installer Sync / macos-installer (push) Has been cancelled
Website Installer Sync / windows-installer (push) Has been cancelled
Website Installer Sync / sync-website (push) Has been cancelled
Some checks failed
ClawSweeper Dispatch / dispatch (push) Has been cancelled
CodeQL / Security High (actions) (push) Has been cancelled
CodeQL / Security High (channel-runtime-boundary) (push) Has been cancelled
CodeQL / Security High (core-auth-secrets) (push) Has been cancelled
CodeQL / Security High (mcp-process-tool-boundary) (push) Has been cancelled
CodeQL / Security High (network-ssrf-boundary) (push) Has been cancelled
CodeQL / Security High (plugin-trust-boundary) (push) Has been cancelled
CodeQL / Security High (process-exec-boundary) (push) Has been cancelled
Docs Sync Publish Repo / sync-publish-repo (push) Has been cancelled
Docs / docs (push) Has been cancelled
OpenClaw Stable Main Closeout / Resolve stable release closeout inputs (push) Has been cancelled
OpenClaw Stable Main Closeout / Verify stable main closeout (push) Has been cancelled
Workflow Sanity / no-tabs (push) Has been cancelled
Workflow Sanity / actionlint (push) Has been cancelled
Workflow Sanity / generated-doc-baselines (push) Has been cancelled
CI / runner-admission (push) Has been cancelled
CI / preflight (push) Has been cancelled
CI / security-fast (push) Has been cancelled
CI / pnpm-store-warmup (push) Has been cancelled
CI / build-artifacts (push) Has been cancelled
CI / native-i18n (push) Has been cancelled
CI / ${{ matrix.check_name }} (push) Has been cancelled
CI / ${{ matrix.checkName }} (push) Has been cancelled
CI / checks-node-compat-node22 (push) Has been cancelled
CI / check-bundled-channel-config-metadata (push) Has been cancelled
CI / check-dependencies (push) Has been cancelled
CI / check-guards (push) Has been cancelled
CI / check-lint (push) Has been cancelled
CI / check-prod-types (push) Has been cancelled
CI / check-shrinkwrap (push) Has been cancelled
CI / check-test-types (push) Has been cancelled
CI / check-additional-boundaries-a (push) Has been cancelled
CI / check-additional-boundaries-bcd (push) Has been cancelled
CI / check-additional-extension-bundled (push) Has been cancelled
CI / check-additional-extension-channels (push) Has been cancelled
CI / check-additional-extension-package-boundary (push) Has been cancelled
CI / check-additional-runtime-topology-architecture (push) Has been cancelled
CI / check-session-accessor-boundary (push) Has been cancelled
CI / check-session-transcript-reader-boundary (push) Has been cancelled
CI / check-docs (push) Has been cancelled
CI / skills-python (push) Has been cancelled
CI / macos-swift (push) Has been cancelled
CI / ios-build (push) Has been cancelled
CI / ci-timings-summary (push) Has been cancelled
Native App Locale Refresh / Refresh native fa (push) Has been cancelled
Native App Locale Refresh / Refresh native fr (push) Has been cancelled
Native App Locale Refresh / Refresh native hi (push) Has been cancelled
Native App Locale Refresh / Refresh native id (push) Has been cancelled
Native App Locale Refresh / Refresh native it (push) Has been cancelled
Native App Locale Refresh / Refresh native ja-JP (push) Has been cancelled
Control UI Locale Refresh / plan (push) Has been cancelled
Control UI Locale Refresh / Refresh ${{ matrix.locale }} (push) Has been cancelled
Control UI Locale Refresh / Commit control UI locale refresh (push) Has been cancelled
Live Media Runner Image / Build live media runner image (push) Has been cancelled
Native App Locale Refresh / Refresh native ar (push) Has been cancelled
Native App Locale Refresh / Refresh native de (push) Has been cancelled
Native App Locale Refresh / Refresh native es (push) Has been cancelled
Native App Locale Refresh / Refresh native ko (push) Has been cancelled
Native App Locale Refresh / Refresh native nl (push) Has been cancelled
Native App Locale Refresh / Refresh native pl (push) Has been cancelled
Native App Locale Refresh / Refresh native pt-BR (push) Has been cancelled
Native App Locale Refresh / Refresh native ru (push) Has been cancelled
Native App Locale Refresh / Refresh native sv (push) Has been cancelled
Native App Locale Refresh / Refresh native th (push) Has been cancelled
Native App Locale Refresh / Refresh native tr (push) Has been cancelled
Native App Locale Refresh / Refresh native uk (push) Has been cancelled
Native App Locale Refresh / Refresh native vi (push) Has been cancelled
Native App Locale Refresh / Refresh native zh-CN (push) Has been cancelled
Native App Locale Refresh / Refresh native zh-TW (push) Has been cancelled
Native App Locale Refresh / Commit native locale refresh (push) Has been cancelled
Plugin Init Scaffold Validation / Validate provider scaffold (push) Has been cancelled
Plugin NPM Release / preview_plugins_npm (push) Has been cancelled
Plugin NPM Release / Validate release publish approval (push) Has been cancelled
Plugin NPM Release / preview_plugin_pack (push) Has been cancelled
Plugin NPM Release / publish_plugins_npm (push) Has been cancelled
Sandbox Common Smoke / sandbox-common-smoke (push) Has been cancelled
Website Installer Sync / static (push) Has been cancelled
Website Installer Sync / linux-docker (push) Has been cancelled
Website Installer Sync / macos-installer (push) Has been cancelled
Website Installer Sync / windows-installer (push) Has been cancelled
Website Installer Sync / sync-website (push) Has been cancelled
Adolf is a fork/vendored clone of github.com/openclaw/openclaw (v2026.6.11), free to diverge. Tree copied sans upstream .git; upstream remote added for future syncs. Node pinned to 24 (.nvmrc); engines already require >=22.19. Preserves docs/ARCHITECTURE.md. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LeqyaxJF2nbRXJtae2kNB2
This commit is contained in:
379
extensions/codex/src/conversation-control.ts
Normal file
379
extensions/codex/src/conversation-control.ts
Normal file
@@ -0,0 +1,379 @@
|
||||
// Codex plugin module implements conversation control behavior.
|
||||
import { CODEX_CONTROL_METHODS } from "./app-server/capabilities.js";
|
||||
import {
|
||||
isCodexFastServiceTier,
|
||||
resolveCodexModelBackedReviewerPolicyContext,
|
||||
resolveCodexAppServerRuntimeOptions,
|
||||
type CodexAppServerApprovalPolicy,
|
||||
type CodexAppServerSandboxMode,
|
||||
} from "./app-server/config.js";
|
||||
import type { CodexServiceTier, CodexThreadResumeResponse } from "./app-server/protocol.js";
|
||||
import {
|
||||
isCodexAppServerNativeAuthProfile,
|
||||
readCodexAppServerBinding,
|
||||
writeCodexAppServerBinding,
|
||||
} from "./app-server/session-binding.js";
|
||||
import {
|
||||
getLeasedSharedCodexAppServerClient,
|
||||
releaseLeasedSharedCodexAppServerClient,
|
||||
} from "./app-server/shared-client.js";
|
||||
import {
|
||||
resolveCodexAppServerRequestModelSelection,
|
||||
resolveCodexBindingModelProviderFallback,
|
||||
} from "./app-server/thread-lifecycle.js";
|
||||
import { formatCodexDisplayText } from "./command-formatters.js";
|
||||
|
||||
type ActiveTurn = {
|
||||
sessionFile: string;
|
||||
threadId: string;
|
||||
turnId: string;
|
||||
};
|
||||
|
||||
type CodexAppServerBindingLookup = NonNullable<Parameters<typeof readCodexAppServerBinding>[1]>;
|
||||
|
||||
type PermissionsMode = "default" | "yolo";
|
||||
|
||||
const CODEX_CONVERSATION_CONTROL_STATE = Symbol.for("openclaw.codex.conversationControl");
|
||||
|
||||
function getActiveTurns(): Map<string, ActiveTurn> {
|
||||
const globalState = globalThis as typeof globalThis & {
|
||||
[CODEX_CONVERSATION_CONTROL_STATE]?: Map<string, ActiveTurn>;
|
||||
};
|
||||
globalState[CODEX_CONVERSATION_CONTROL_STATE] ??= new Map();
|
||||
return globalState[CODEX_CONVERSATION_CONTROL_STATE];
|
||||
}
|
||||
|
||||
export function trackCodexConversationActiveTurn(active: ActiveTurn): () => void {
|
||||
const activeTurns = getActiveTurns();
|
||||
activeTurns.set(active.sessionFile, active);
|
||||
return () => {
|
||||
const current = activeTurns.get(active.sessionFile);
|
||||
if (current?.turnId === active.turnId) {
|
||||
activeTurns.delete(active.sessionFile);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function readCodexConversationActiveTurn(sessionFile: string): ActiveTurn | undefined {
|
||||
return getActiveTurns().get(sessionFile);
|
||||
}
|
||||
|
||||
export async function stopCodexConversationTurn(params: {
|
||||
sessionFile: string;
|
||||
pluginConfig?: unknown;
|
||||
agentDir?: string;
|
||||
config?: CodexAppServerBindingLookup["config"];
|
||||
}): Promise<{ stopped: boolean; message: string }> {
|
||||
const active = readCodexConversationActiveTurn(params.sessionFile);
|
||||
if (!active) {
|
||||
return { stopped: false, message: "No active Codex run to stop." };
|
||||
}
|
||||
const runtime = resolveCodexAppServerRuntimeOptions({ pluginConfig: params.pluginConfig });
|
||||
const lookup = buildBindingLookup(params);
|
||||
const binding = await readCodexAppServerBinding(params.sessionFile, lookup);
|
||||
const client = await getLeasedSharedCodexAppServerClient({
|
||||
startOptions: runtime.start,
|
||||
timeoutMs: runtime.requestTimeoutMs,
|
||||
authProfileId: binding?.authProfileId,
|
||||
...lookup,
|
||||
});
|
||||
try {
|
||||
await client.request(
|
||||
"turn/interrupt",
|
||||
{
|
||||
threadId: active.threadId,
|
||||
turnId: active.turnId,
|
||||
},
|
||||
{ timeoutMs: runtime.requestTimeoutMs },
|
||||
);
|
||||
} finally {
|
||||
releaseLeasedSharedCodexAppServerClient(client);
|
||||
}
|
||||
return { stopped: true, message: "Codex stop requested." };
|
||||
}
|
||||
|
||||
export async function steerCodexConversationTurn(params: {
|
||||
sessionFile: string;
|
||||
message: string;
|
||||
pluginConfig?: unknown;
|
||||
agentDir?: string;
|
||||
config?: CodexAppServerBindingLookup["config"];
|
||||
}): Promise<{ steered: boolean; message: string }> {
|
||||
const active = readCodexConversationActiveTurn(params.sessionFile);
|
||||
const text = params.message.trim();
|
||||
if (!text) {
|
||||
return { steered: false, message: "Usage: /codex steer <message>" };
|
||||
}
|
||||
if (!active) {
|
||||
return { steered: false, message: "No active Codex run to steer." };
|
||||
}
|
||||
const runtime = resolveCodexAppServerRuntimeOptions({ pluginConfig: params.pluginConfig });
|
||||
const lookup = buildBindingLookup(params);
|
||||
const binding = await readCodexAppServerBinding(params.sessionFile, lookup);
|
||||
const client = await getLeasedSharedCodexAppServerClient({
|
||||
startOptions: runtime.start,
|
||||
timeoutMs: runtime.requestTimeoutMs,
|
||||
authProfileId: binding?.authProfileId,
|
||||
...lookup,
|
||||
});
|
||||
try {
|
||||
await client.request(
|
||||
"turn/steer",
|
||||
{
|
||||
threadId: active.threadId,
|
||||
expectedTurnId: active.turnId,
|
||||
input: [{ type: "text", text, text_elements: [] }],
|
||||
},
|
||||
{ timeoutMs: runtime.requestTimeoutMs },
|
||||
);
|
||||
} finally {
|
||||
releaseLeasedSharedCodexAppServerClient(client);
|
||||
}
|
||||
return { steered: true, message: "Sent steer message to Codex." };
|
||||
}
|
||||
|
||||
export async function setCodexConversationModel(params: {
|
||||
sessionFile: string;
|
||||
model: string;
|
||||
pluginConfig?: unknown;
|
||||
agentDir?: string;
|
||||
config?: CodexAppServerBindingLookup["config"];
|
||||
}): Promise<string> {
|
||||
const model = params.model.trim();
|
||||
if (!model) {
|
||||
return "Usage: /codex model <model>";
|
||||
}
|
||||
const lookup = buildBindingLookup(params);
|
||||
const binding = await requireThreadBinding(params.sessionFile, lookup);
|
||||
const reviewerPolicyContext = resolveCodexModelBackedReviewerPolicyContext({
|
||||
provider: "codex",
|
||||
model,
|
||||
bindingModelProvider: binding.modelProvider,
|
||||
bindingModel: binding.model,
|
||||
nativeAuthProfile: isCodexAppServerNativeAuthProfile({
|
||||
authProfileId: binding.authProfileId,
|
||||
...lookup,
|
||||
}),
|
||||
});
|
||||
const runtime = resolveCodexAppServerRuntimeOptions({
|
||||
pluginConfig: params.pluginConfig,
|
||||
modelProvider: reviewerPolicyContext.modelProvider,
|
||||
model: reviewerPolicyContext.model,
|
||||
config: params.config,
|
||||
agentDir: params.agentDir,
|
||||
});
|
||||
const modelProvider = resolveConversationControlModelProvider({
|
||||
authProfileId: binding.authProfileId,
|
||||
bindingModel: binding.model,
|
||||
bindingModelProvider: binding.modelProvider,
|
||||
currentModel: model,
|
||||
...lookup,
|
||||
});
|
||||
const modelSelection = resolveCodexAppServerRequestModelSelection({
|
||||
model,
|
||||
modelProvider,
|
||||
authProfileId: binding.authProfileId,
|
||||
...lookup,
|
||||
});
|
||||
const response = await resumeThreadWithOverrides({
|
||||
runtime,
|
||||
threadId: binding.threadId,
|
||||
authProfileId: binding.authProfileId,
|
||||
...lookup,
|
||||
model: modelSelection.model,
|
||||
modelProvider: modelSelection.modelProvider,
|
||||
});
|
||||
await writeCodexAppServerBinding(
|
||||
params.sessionFile,
|
||||
{
|
||||
...binding,
|
||||
cwd: response.thread.cwd ?? binding.cwd,
|
||||
model: response.model ?? modelSelection.model,
|
||||
modelProvider: response.modelProvider ?? modelSelection.modelProvider,
|
||||
approvalPolicy: binding.approvalPolicy,
|
||||
sandbox: binding.sandbox,
|
||||
serviceTier: binding.serviceTier ?? runtime.serviceTier ?? undefined,
|
||||
},
|
||||
lookup,
|
||||
);
|
||||
return `Codex model set to ${formatCodexDisplayText(response.model ?? model)}.`;
|
||||
}
|
||||
|
||||
export async function setCodexConversationFastMode(params: {
|
||||
sessionFile: string;
|
||||
enabled?: boolean;
|
||||
pluginConfig?: unknown;
|
||||
agentDir?: string;
|
||||
config?: CodexAppServerBindingLookup["config"];
|
||||
}): Promise<string> {
|
||||
const lookup = buildBindingLookup(params);
|
||||
const binding = await requireThreadBinding(params.sessionFile, lookup);
|
||||
if (params.enabled == null) {
|
||||
return `Codex fast mode: ${isCodexFastServiceTier(binding.serviceTier) ? "on" : "off"}.`;
|
||||
}
|
||||
const serviceTier: CodexServiceTier = params.enabled ? "priority" : "flex";
|
||||
// Fast mode is sent on each later turn; do not require Codex to accept an
|
||||
// immediate thread/resume control request just to persist the preference.
|
||||
await writeCodexAppServerBinding(
|
||||
params.sessionFile,
|
||||
{
|
||||
...binding,
|
||||
serviceTier,
|
||||
},
|
||||
lookup,
|
||||
);
|
||||
return `Codex fast mode ${params.enabled ? "enabled" : "disabled"}.`;
|
||||
}
|
||||
|
||||
export async function setCodexConversationPermissions(params: {
|
||||
sessionFile: string;
|
||||
mode?: PermissionsMode;
|
||||
pluginConfig?: unknown;
|
||||
agentDir?: string;
|
||||
config?: CodexAppServerBindingLookup["config"];
|
||||
}): Promise<string> {
|
||||
const lookup = buildBindingLookup(params);
|
||||
const binding = await requireThreadBinding(params.sessionFile, lookup);
|
||||
if (!params.mode) {
|
||||
return `Codex permissions: ${formatPermissionsMode(binding)}.`;
|
||||
}
|
||||
const policy = permissionsForMode(params.mode);
|
||||
// Native bound turns pass these settings at turn/start time, so this command
|
||||
// can update the local binding even when app-server resume overrides fail.
|
||||
await writeCodexAppServerBinding(
|
||||
params.sessionFile,
|
||||
{
|
||||
...binding,
|
||||
approvalPolicy: policy.approvalPolicy,
|
||||
sandbox: policy.sandbox,
|
||||
},
|
||||
lookup,
|
||||
);
|
||||
return `Codex permissions set to ${params.mode === "yolo" ? "full access" : "default"}.`;
|
||||
}
|
||||
|
||||
export function parseCodexFastModeArg(arg: string | undefined): boolean | undefined {
|
||||
const normalized = arg?.trim().toLowerCase();
|
||||
if (!normalized || normalized === "status") {
|
||||
return undefined;
|
||||
}
|
||||
if (normalized === "on" || normalized === "true" || normalized === "fast") {
|
||||
return true;
|
||||
}
|
||||
if (normalized === "off" || normalized === "false" || normalized === "flex") {
|
||||
return false;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function parseCodexPermissionsModeArg(arg: string | undefined): PermissionsMode | undefined {
|
||||
const normalized = arg?.trim().toLowerCase();
|
||||
if (!normalized || normalized === "status") {
|
||||
return undefined;
|
||||
}
|
||||
if (normalized === "yolo" || normalized === "full" || normalized === "full-access") {
|
||||
return "yolo";
|
||||
}
|
||||
if (normalized === "default" || normalized === "guardian") {
|
||||
return "default";
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function formatPermissionsMode(binding: {
|
||||
approvalPolicy?: CodexAppServerApprovalPolicy;
|
||||
sandbox?: CodexAppServerSandboxMode;
|
||||
}): string {
|
||||
return binding.approvalPolicy === "never" && binding.sandbox === "danger-full-access"
|
||||
? "full access"
|
||||
: "default";
|
||||
}
|
||||
|
||||
async function requireThreadBinding(sessionFile: string, lookup: CodexAppServerBindingLookup = {}) {
|
||||
const binding = await readCodexAppServerBinding(sessionFile, lookup);
|
||||
if (!binding?.threadId) {
|
||||
throw new Error("No Codex thread is attached to this OpenClaw session yet.");
|
||||
}
|
||||
return binding;
|
||||
}
|
||||
|
||||
async function resumeThreadWithOverrides(params: {
|
||||
runtime: ReturnType<typeof resolveCodexAppServerRuntimeOptions>;
|
||||
threadId: string;
|
||||
authProfileId?: string;
|
||||
agentDir?: string;
|
||||
config?: CodexAppServerBindingLookup["config"];
|
||||
model?: string;
|
||||
modelProvider?: string | null;
|
||||
approvalPolicy?: CodexAppServerApprovalPolicy;
|
||||
sandbox?: CodexAppServerSandboxMode;
|
||||
serviceTier?: CodexServiceTier;
|
||||
}): Promise<CodexThreadResumeResponse> {
|
||||
const runtime = params.runtime;
|
||||
const client = await getLeasedSharedCodexAppServerClient({
|
||||
startOptions: runtime.start,
|
||||
timeoutMs: runtime.requestTimeoutMs,
|
||||
authProfileId: params.authProfileId,
|
||||
...buildBindingLookup(params),
|
||||
});
|
||||
try {
|
||||
return await client.request(
|
||||
CODEX_CONTROL_METHODS.resumeThread,
|
||||
{
|
||||
threadId: params.threadId,
|
||||
...(params.model ? { model: params.model } : {}),
|
||||
...(params.modelProvider ? { modelProvider: params.modelProvider } : {}),
|
||||
approvalPolicy: params.approvalPolicy ?? runtime.approvalPolicy,
|
||||
sandbox: params.sandbox ?? runtime.sandbox,
|
||||
approvalsReviewer: runtime.approvalsReviewer,
|
||||
...(params.serviceTier ? { serviceTier: params.serviceTier } : {}),
|
||||
persistExtendedHistory: true,
|
||||
},
|
||||
{ timeoutMs: runtime.requestTimeoutMs },
|
||||
);
|
||||
} finally {
|
||||
releaseLeasedSharedCodexAppServerClient(client);
|
||||
}
|
||||
}
|
||||
|
||||
function buildBindingLookup(params: {
|
||||
agentDir?: string;
|
||||
config?: CodexAppServerBindingLookup["config"];
|
||||
}): CodexAppServerBindingLookup {
|
||||
const agentDir = params.agentDir?.trim();
|
||||
return {
|
||||
...(agentDir ? { agentDir } : {}),
|
||||
...(params.config ? { config: params.config } : {}),
|
||||
};
|
||||
}
|
||||
|
||||
function resolveConversationControlModelProvider(params: {
|
||||
authProfileId?: string;
|
||||
bindingModel?: string;
|
||||
bindingModelProvider?: string;
|
||||
currentModel?: string;
|
||||
agentDir?: string;
|
||||
config?: CodexAppServerBindingLookup["config"];
|
||||
}): string | undefined {
|
||||
const modelProvider = resolveCodexBindingModelProviderFallback({
|
||||
currentModel: params.currentModel,
|
||||
bindingModel: params.bindingModel,
|
||||
bindingModelProvider: params.bindingModelProvider,
|
||||
})?.trim();
|
||||
if (!modelProvider || modelProvider.toLowerCase() === "codex") {
|
||||
return undefined;
|
||||
}
|
||||
if (isCodexAppServerNativeAuthProfile(params) && modelProvider.toLowerCase() === "openai") {
|
||||
return undefined;
|
||||
}
|
||||
return modelProvider.toLowerCase() === "openai" ? "openai" : modelProvider;
|
||||
}
|
||||
|
||||
function permissionsForMode(mode: PermissionsMode): {
|
||||
approvalPolicy: CodexAppServerApprovalPolicy;
|
||||
sandbox: CodexAppServerSandboxMode;
|
||||
} {
|
||||
return mode === "yolo"
|
||||
? { approvalPolicy: "never", sandbox: "danger-full-access" }
|
||||
: { approvalPolicy: "on-request", sandbox: "workspace-write" };
|
||||
}
|
||||
Reference in New Issue
Block a user