@openclaw/codex 2026.5.14-beta.2 → 2026.5.16-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{client-CoctX13d.js → client-CA7amCZ8.js} +1 -1
- package/dist/{client-factory-Be6RD28K.js → client-factory-DwzPofwS.js} +1 -1
- package/dist/{command-formatters-DRJaVHhN.js → command-formatters-BRW7_Nu7.js} +10 -2
- package/dist/{command-handlers-CXxykxjq.js → command-handlers-D6UDzndR.js} +7 -7
- package/dist/compact-96QPqIAu.js +329 -0
- package/dist/{computer-use-DsJxRRtm.js → computer-use-BX02ojP4.js} +2 -2
- package/dist/{config-0rd3LnKg.js → config-3ATInASk.js} +7 -1
- package/dist/harness.js +9 -6
- package/dist/index.js +7 -7
- package/dist/media-understanding-provider.js +3 -3
- package/dist/{models-GCYf5s8J.js → models-BHS-8DS_.js} +1 -1
- package/dist/{node-cli-sessions-CiexDHeV.js → node-cli-sessions-BLDFnUEF.js} +5 -5
- package/dist/{plugin-activation-aQOmRQwA.js → plugin-activation-BDU4e-NA.js} +1 -1
- package/dist/provider.js +2 -2
- package/dist/{request-CKYiRqsN.js → request-Czoa60Nt.js} +3 -3
- package/dist/{run-attempt-DG9NQab2.js → run-attempt-B6gN6CrO.js} +364 -77
- package/dist/{session-binding-CMTXuyoz.js → session-binding-DbdVqMzW.js} +14 -2
- package/dist/{shared-client-BwUqd3lh.js → shared-client-CnbrvEfV.js} +2 -2
- package/dist/{side-question-CVWPOkY-.js → side-question-CFcVH8fj.js} +7 -7
- package/dist/test-api.js +2 -2
- package/dist/{thread-lifecycle-DrbViNpf.js → thread-lifecycle-BMK4m_PL.js} +159 -34
- package/dist/{vision-tools-CzTdigBu.js → vision-tools-Cm_YicZb.js} +107 -7
- package/openclaw.plugin.json +1 -1
- package/package.json +4 -4
- package/dist/compact-DWa8cylR.js +0 -256
|
@@ -1,28 +1,28 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { c as resolveCodexAppServerRuntimeOptions, d as withMcpElicitationsApprovalPolicy, i as isCodexAppServerApprovalPolicyAllowedByRequirements, s as readCodexPluginConfig, u as resolveCodexPluginsPolicy } from "./config-3ATInASk.js";
|
|
2
2
|
import { a as readCodexDynamicToolCallParams, c as readCodexTurn, i as assertCodexTurnStartResponse } from "./protocol-validators-CSY0BFBo.js";
|
|
3
3
|
import { t as isJsonObject } from "./protocol-C9UWI98H.js";
|
|
4
|
-
import { i as isCodexAppServerConnectionClosedError, r as isCodexAppServerApprovalRequest } from "./client-
|
|
5
|
-
import { n as buildCodexPluginAppCacheKey, r as CODEX_CONTROL_METHODS } from "./request-
|
|
6
|
-
import { d as resolveCodexUsageLimitResetAtMs, f as shouldRefreshCodexRateLimitsForUsageLimitMessage, r as formatCodexDisplayText, u as formatCodexUsageLimitErrorMessage } from "./command-formatters-
|
|
7
|
-
import { c as resolveCodexAppServerAuthAccountCacheKey, d as resolveCodexAppServerEnvApiKeyCacheKey, l as resolveCodexAppServerAuthProfileId, n as clearSharedCodexAppServerClientIfCurrent, s as refreshCodexAppServerAuthTokens, u as resolveCodexAppServerAuthProfileIdForAgent } from "./shared-client-
|
|
8
|
-
import { i as readCodexAppServerBinding, t as clearCodexAppServerBinding } from "./session-binding-
|
|
9
|
-
import { a as defaultCodexAppInventoryCache } from "./plugin-activation-
|
|
10
|
-
import { _ as
|
|
11
|
-
import { t as defaultCodexAppServerClientFactory } from "./client-factory-
|
|
12
|
-
import { n as handleCodexAppServerElicitationRequest, r as handleCodexAppServerApprovalRequest, t as filterToolsForVisionInputs } from "./vision-tools-
|
|
13
|
-
import { t as ensureCodexComputerUse } from "./computer-use-
|
|
4
|
+
import { i as isCodexAppServerConnectionClosedError, r as isCodexAppServerApprovalRequest } from "./client-CA7amCZ8.js";
|
|
5
|
+
import { n as buildCodexPluginAppCacheKey, r as CODEX_CONTROL_METHODS } from "./request-Czoa60Nt.js";
|
|
6
|
+
import { d as resolveCodexUsageLimitResetAtMs, f as shouldRefreshCodexRateLimitsForUsageLimitMessage, r as formatCodexDisplayText, u as formatCodexUsageLimitErrorMessage } from "./command-formatters-BRW7_Nu7.js";
|
|
7
|
+
import { c as resolveCodexAppServerAuthAccountCacheKey, d as resolveCodexAppServerEnvApiKeyCacheKey, l as resolveCodexAppServerAuthProfileId, n as clearSharedCodexAppServerClientIfCurrent, s as refreshCodexAppServerAuthTokens, u as resolveCodexAppServerAuthProfileIdForAgent } from "./shared-client-CnbrvEfV.js";
|
|
8
|
+
import { i as readCodexAppServerBinding, t as clearCodexAppServerBinding } from "./session-binding-DbdVqMzW.js";
|
|
9
|
+
import { a as defaultCodexAppInventoryCache } from "./plugin-activation-BDU4e-NA.js";
|
|
10
|
+
import { S as normalizeCodexDynamicToolName, _ as projectContextEngineAssemblyForCodex, b as createCodexDynamicToolBridge, c as codexDynamicToolsFingerprint, f as startOrResumeThread, g as shouldBuildCodexPluginThreadConfig, h as mergeCodexThreadConfigs, i as buildDeveloperInstructions, l as isContextEngineBindingCompatible, m as buildCodexPluginThreadConfigInputFingerprint, p as buildCodexPluginThreadConfig, r as buildContextEngineBinding, s as buildTurnStartParams, t as areCodexDynamicToolFingerprintsCompatible, v as resolveCodexContextEngineProjectionMaxChars, x as filterCodexDynamicTools, y as resolveCodexContextEngineProjectionReserveTokens } from "./thread-lifecycle-BMK4m_PL.js";
|
|
11
|
+
import { t as defaultCodexAppServerClientFactory } from "./client-factory-DwzPofwS.js";
|
|
12
|
+
import { n as handleCodexAppServerElicitationRequest, r as handleCodexAppServerApprovalRequest, t as filterToolsForVisionInputs } from "./vision-tools-Cm_YicZb.js";
|
|
13
|
+
import { t as ensureCodexComputerUse } from "./computer-use-BX02ojP4.js";
|
|
14
14
|
import { n as rememberCodexRateLimits, t as readRecentCodexRateLimits } from "./rate-limit-cache-dvhq-4pi.js";
|
|
15
15
|
import { createHash } from "node:crypto";
|
|
16
16
|
import nodeFs from "node:fs";
|
|
17
|
-
import { TOOL_PROGRESS_OUTPUT_MAX_CHARS, acquireSessionWriteLock, appendSessionTranscriptMessage, assembleHarnessContextEngine, bootstrapHarnessContextEngine, buildEmbeddedAttemptToolRunContext, buildHarnessContextEngineRuntimeContext, buildHarnessContextEngineRuntimeContextFromUsage, classifyAgentHarnessTerminalOutcome, clearActiveEmbeddedRun, embeddedAgentLog, emitAgentEvent, emitSessionTranscriptUpdate, finalizeHarnessContextEngineTurn, formatErrorMessage, formatToolAggregate, formatToolProgressOutput, inferToolMetaFromArgs, isActiveHarnessContextEngine, isSubagentSessionKey, loadCodexBundleMcpThreadConfig, normalizeAgentRuntimeTools, normalizeUsage, registerNativeHookRelay, resolveAgentHarnessBeforePromptBuildResult, resolveAttemptSpawnWorkspaceDir, resolveBootstrapContextForRun, resolveModelAuthMode, resolveSandboxContext, resolveSessionAgentIds, resolveSessionWriteLockAcquireTimeoutMs, resolveUserPath, runAgentCleanupStep, runAgentHarnessAfterCompactionHook, runAgentHarnessAfterToolCallHook, runAgentHarnessAgentEndHook, runAgentHarnessBeforeCompactionHook, runAgentHarnessBeforeMessageWriteHook, runAgentHarnessLlmInputHook, runAgentHarnessLlmOutputHook, runHarnessContextEngineMaintenance, setActiveEmbeddedRun, supportsModelTools } from "openclaw/plugin-sdk/agent-harness-runtime";
|
|
17
|
+
import { TOOL_PROGRESS_OUTPUT_MAX_CHARS, acquireSessionWriteLock, appendSessionTranscriptMessage, assembleHarnessContextEngine, bootstrapHarnessContextEngine, buildEmbeddedAttemptToolRunContext, buildHarnessContextEngineRuntimeContext, buildHarnessContextEngineRuntimeContextFromUsage, classifyAgentHarnessTerminalOutcome, clearActiveEmbeddedRun, embeddedAgentLog, emitAgentEvent, emitSessionTranscriptUpdate, finalizeHarnessContextEngineTurn, formatErrorMessage, formatToolAggregate, formatToolProgressOutput, hasBeforeToolCallPolicy, inferToolMetaFromArgs, isActiveHarnessContextEngine, isSubagentSessionKey, loadCodexBundleMcpThreadConfig, normalizeAgentRuntimeTools, normalizeUsage, registerNativeHookRelay, resolveAgentHarnessBeforePromptBuildResult, resolveAttemptSpawnWorkspaceDir, resolveBootstrapContextForRun, resolveContextEngineOwnerPluginId, resolveModelAuthMode, resolveSandboxContext, resolveSessionAgentIds, resolveSessionWriteLockAcquireTimeoutMs, resolveUserPath, runAgentCleanupStep, runAgentHarnessAfterCompactionHook, runAgentHarnessAfterToolCallHook, runAgentHarnessAgentEndHook, runAgentHarnessBeforeCompactionHook, runAgentHarnessBeforeMessageWriteHook, runAgentHarnessLlmInputHook, runAgentHarnessLlmOutputHook, runHarnessContextEngineMaintenance, setActiveEmbeddedRun, supportsModelTools } from "openclaw/plugin-sdk/agent-harness-runtime";
|
|
18
18
|
import fs from "node:fs/promises";
|
|
19
19
|
import path from "node:path";
|
|
20
20
|
import { markAuthProfileBlockedUntil, resolveAgentDir as resolveAgentDir$1 } from "openclaw/plugin-sdk/agent-runtime";
|
|
21
21
|
import { appendRegularFile, pathExists } from "openclaw/plugin-sdk/security-runtime";
|
|
22
|
+
import { redactSensitiveFieldValue, redactToolPayloadText } from "openclaw/plugin-sdk/logging-core";
|
|
22
23
|
import { emitTrustedDiagnosticEvent } from "openclaw/plugin-sdk/diagnostic-runtime";
|
|
23
24
|
import { createRunningTaskRun, finalizeTaskRunByRunId, recordTaskRunProgressByRunId } from "openclaw/plugin-sdk/codex-native-task-runtime";
|
|
24
25
|
import { buildSessionContext, migrateSessionEntries, parseSessionEntries } from "@earendil-works/pi-coding-agent";
|
|
25
|
-
import { redactSensitiveFieldValue, redactToolPayloadText } from "openclaw/plugin-sdk/logging-core";
|
|
26
26
|
//#region extensions/codex/src/app-server/native-subagent-task-mirror.ts
|
|
27
27
|
const CODEX_NATIVE_SUBAGENT_RUNTIME = "subagent";
|
|
28
28
|
const CODEX_NATIVE_SUBAGENT_TASK_KIND = "codex-native";
|
|
@@ -347,6 +347,41 @@ function inferCodexDynamicToolMeta(call, detailMode) {
|
|
|
347
347
|
//#endregion
|
|
348
348
|
//#region extensions/codex/src/app-server/transcript-mirror.ts
|
|
349
349
|
const MIRROR_IDENTITY_META_KEY = "mirrorIdentity";
|
|
350
|
+
function normalizeOptionalString(value) {
|
|
351
|
+
const normalized = value?.trim();
|
|
352
|
+
return normalized ? normalized : void 0;
|
|
353
|
+
}
|
|
354
|
+
function buildSenderLabel(params) {
|
|
355
|
+
const label = params.senderName ?? params.senderUsername ?? params.senderE164 ?? params.senderId;
|
|
356
|
+
if (!label) return;
|
|
357
|
+
if (!params.senderId || label.includes(params.senderId)) return label;
|
|
358
|
+
return `${label} (${params.senderId})`;
|
|
359
|
+
}
|
|
360
|
+
function buildCodexUserPromptMessage(params) {
|
|
361
|
+
const senderId = normalizeOptionalString(params.senderId);
|
|
362
|
+
const senderName = normalizeOptionalString(params.senderName);
|
|
363
|
+
const senderUsername = normalizeOptionalString(params.senderUsername);
|
|
364
|
+
const senderE164 = normalizeOptionalString(params.senderE164);
|
|
365
|
+
const senderLabel = buildSenderLabel({
|
|
366
|
+
senderId,
|
|
367
|
+
senderName,
|
|
368
|
+
senderUsername,
|
|
369
|
+
senderE164
|
|
370
|
+
});
|
|
371
|
+
const sourceChannel = normalizeOptionalString(params.inputProvenance?.sourceChannel ?? params.messageChannel ?? params.messageProvider);
|
|
372
|
+
return {
|
|
373
|
+
role: "user",
|
|
374
|
+
content: params.prompt,
|
|
375
|
+
timestamp: Date.now(),
|
|
376
|
+
...params.inputProvenance ? { provenance: params.inputProvenance } : {},
|
|
377
|
+
...sourceChannel ? { sourceChannel } : {},
|
|
378
|
+
...senderId ? { senderId } : {},
|
|
379
|
+
...senderName ? { senderName } : {},
|
|
380
|
+
...senderUsername ? { senderUsername } : {},
|
|
381
|
+
...senderE164 ? { senderE164 } : {},
|
|
382
|
+
...senderLabel ? { senderLabel } : {}
|
|
383
|
+
};
|
|
384
|
+
}
|
|
350
385
|
/**
|
|
351
386
|
* Tag a message with a stable logical identity for mirror dedupe. Callers
|
|
352
387
|
* should use a value that is invariant for the same logical message across
|
|
@@ -596,11 +631,7 @@ var CodexAppServerEventProjector = class {
|
|
|
596
631
|
const planText = collectTextValues(this.planTextByItem).join("\n\n");
|
|
597
632
|
const lastAssistant = assistantTexts.length > 0 ? this.createAssistantMessage(assistantTexts.join("\n\n")) : void 0;
|
|
598
633
|
const turnId = this.turnId;
|
|
599
|
-
const messagesSnapshot = [attachCodexMirrorIdentity({
|
|
600
|
-
role: "user",
|
|
601
|
-
content: this.params.prompt,
|
|
602
|
-
timestamp: Date.now()
|
|
603
|
-
}, `${turnId}:prompt`)];
|
|
634
|
+
const messagesSnapshot = [attachCodexMirrorIdentity(buildCodexUserPromptMessage(this.params), `${turnId}:prompt`)];
|
|
604
635
|
if (reasoningText) messagesSnapshot.push(attachCodexMirrorIdentity(this.createAssistantMirrorMessage("Codex reasoning", reasoningText), `${turnId}:reasoning`));
|
|
605
636
|
if (planText) messagesSnapshot.push(attachCodexMirrorIdentity(this.createAssistantMirrorMessage("Codex plan", planText), `${turnId}:plan`));
|
|
606
637
|
messagesSnapshot.push(...this.toolTranscriptMessages);
|
|
@@ -1701,27 +1732,45 @@ const CODEX_HOOK_EVENT_BY_NATIVE_EVENT = {
|
|
|
1701
1732
|
permission_request: "PermissionRequest",
|
|
1702
1733
|
before_agent_finalize: "Stop"
|
|
1703
1734
|
};
|
|
1735
|
+
const CODEX_HOOK_KEY_LABEL_BY_NATIVE_EVENT = {
|
|
1736
|
+
pre_tool_use: "pre_tool_use",
|
|
1737
|
+
post_tool_use: "post_tool_use",
|
|
1738
|
+
permission_request: "permission_request",
|
|
1739
|
+
before_agent_finalize: "stop"
|
|
1740
|
+
};
|
|
1741
|
+
const CODEX_SESSION_FLAGS_HOOK_SOURCE_PATHS = ["/<session-flags>/config.toml", "<session-flags>/config.toml"];
|
|
1704
1742
|
function buildCodexNativeHookRelayConfig(params) {
|
|
1705
1743
|
const events = params.events?.length ? params.events : CODEX_NATIVE_HOOK_RELAY_EVENTS;
|
|
1706
|
-
const config = { "features.
|
|
1744
|
+
const config = { "features.hooks": true };
|
|
1745
|
+
const hookState = {};
|
|
1707
1746
|
for (const event of events) {
|
|
1708
1747
|
const codexEvent = CODEX_HOOK_EVENT_BY_NATIVE_EVENT[event];
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1748
|
+
const command = params.relay.commandForEvent(event);
|
|
1749
|
+
const timeout = normalizeHookTimeoutSec(params.hookTimeoutSec);
|
|
1750
|
+
config[`hooks.${codexEvent}`] = [{ hooks: [{
|
|
1751
|
+
type: "command",
|
|
1752
|
+
command,
|
|
1753
|
+
timeout,
|
|
1754
|
+
async: false,
|
|
1755
|
+
statusMessage: "OpenClaw native hook relay"
|
|
1756
|
+
}] }];
|
|
1757
|
+
const state = {
|
|
1758
|
+
enabled: true,
|
|
1759
|
+
trusted_hash: codexCommandHookTrustedHash({
|
|
1760
|
+
event,
|
|
1761
|
+
command,
|
|
1762
|
+
timeout,
|
|
1716
1763
|
statusMessage: "OpenClaw native hook relay"
|
|
1717
|
-
}
|
|
1718
|
-
}
|
|
1764
|
+
})
|
|
1765
|
+
};
|
|
1766
|
+
for (const sourcePath of CODEX_SESSION_FLAGS_HOOK_SOURCE_PATHS) hookState[`${sourcePath}:${CODEX_HOOK_KEY_LABEL_BY_NATIVE_EVENT[event]}:0:0`] = state;
|
|
1719
1767
|
}
|
|
1768
|
+
config["hooks.state"] = hookState;
|
|
1720
1769
|
return config;
|
|
1721
1770
|
}
|
|
1722
1771
|
function buildCodexNativeHookRelayDisabledConfig() {
|
|
1723
1772
|
return {
|
|
1724
|
-
"features.
|
|
1773
|
+
"features.hooks": false,
|
|
1725
1774
|
"hooks.PreToolUse": [],
|
|
1726
1775
|
"hooks.PostToolUse": [],
|
|
1727
1776
|
"hooks.PermissionRequest": [],
|
|
@@ -1731,6 +1780,26 @@ function buildCodexNativeHookRelayDisabledConfig() {
|
|
|
1731
1780
|
function normalizeHookTimeoutSec(value) {
|
|
1732
1781
|
return typeof value === "number" && Number.isFinite(value) && value > 0 ? Math.ceil(value) : 5;
|
|
1733
1782
|
}
|
|
1783
|
+
function codexCommandHookTrustedHash(params) {
|
|
1784
|
+
const identity = {
|
|
1785
|
+
event_name: CODEX_HOOK_KEY_LABEL_BY_NATIVE_EVENT[params.event],
|
|
1786
|
+
hooks: [{
|
|
1787
|
+
async: false,
|
|
1788
|
+
command: params.command,
|
|
1789
|
+
statusMessage: params.statusMessage,
|
|
1790
|
+
timeout: params.timeout,
|
|
1791
|
+
type: "command"
|
|
1792
|
+
}]
|
|
1793
|
+
};
|
|
1794
|
+
return `sha256:${createHash("sha256").update(JSON.stringify(sortJsonValue(identity))).digest("hex")}`;
|
|
1795
|
+
}
|
|
1796
|
+
function sortJsonValue(value) {
|
|
1797
|
+
if (!value || typeof value !== "object") return value;
|
|
1798
|
+
if (Array.isArray(value)) return value.map(sortJsonValue);
|
|
1799
|
+
const sorted = {};
|
|
1800
|
+
for (const key of Object.keys(value).toSorted()) sorted[key] = sortJsonValue(value[key]);
|
|
1801
|
+
return sorted;
|
|
1802
|
+
}
|
|
1734
1803
|
//#endregion
|
|
1735
1804
|
//#region extensions/codex/src/app-server/trajectory.ts
|
|
1736
1805
|
const SENSITIVE_FIELD_RE = /(?:authorization|cookie|credential|key|password|passwd|secret|token)/iu;
|
|
@@ -2284,6 +2353,22 @@ function restrictCodexAppServerSandboxForOpenClawSandbox(appServer, sandbox) {
|
|
|
2284
2353
|
sandbox: "workspace-write"
|
|
2285
2354
|
};
|
|
2286
2355
|
}
|
|
2356
|
+
function resolveCodexAppServerForOpenClawToolPolicy(params) {
|
|
2357
|
+
if (!params.shouldPromote || !params.canUseUntrustedApprovalPolicy || params.appServer.approvalPolicy !== "never") return params.appServer;
|
|
2358
|
+
const explicitMode = params.pluginConfig.appServer?.mode !== void 0 || isCodexAppServerPolicyMode(params.env.OPENCLAW_CODEX_APP_SERVER_MODE);
|
|
2359
|
+
const explicitApprovalPolicy = params.pluginConfig.appServer?.approvalPolicy !== void 0 || isCodexAppServerApprovalPolicy(params.env.OPENCLAW_CODEX_APP_SERVER_APPROVAL_POLICY);
|
|
2360
|
+
if (explicitMode || explicitApprovalPolicy) return params.appServer;
|
|
2361
|
+
return {
|
|
2362
|
+
...params.appServer,
|
|
2363
|
+
approvalPolicy: "untrusted"
|
|
2364
|
+
};
|
|
2365
|
+
}
|
|
2366
|
+
function isCodexAppServerPolicyMode(value) {
|
|
2367
|
+
return value === "guardian" || value === "yolo";
|
|
2368
|
+
}
|
|
2369
|
+
function isCodexAppServerApprovalPolicy(value) {
|
|
2370
|
+
return value === "never" || value === "on-request" || value === "on-failure" || value === "untrusted";
|
|
2371
|
+
}
|
|
2287
2372
|
async function runCodexAppServerAttempt(params, options = {}) {
|
|
2288
2373
|
const attemptStartedAt = Date.now();
|
|
2289
2374
|
const attemptClientFactory = options.clientFactory ?? defaultCodexAppServerClientFactory;
|
|
@@ -2299,7 +2384,13 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
2299
2384
|
});
|
|
2300
2385
|
const effectiveWorkspace = sandbox?.enabled ? sandbox.workspaceAccess === "rw" ? resolvedWorkspace : sandbox.workspaceDir : resolvedWorkspace;
|
|
2301
2386
|
await fs.mkdir(effectiveWorkspace, { recursive: true });
|
|
2302
|
-
const appServer =
|
|
2387
|
+
const appServer = resolveCodexAppServerForOpenClawToolPolicy({
|
|
2388
|
+
appServer: restrictCodexAppServerSandboxForOpenClawSandbox(configuredAppServer, sandbox),
|
|
2389
|
+
pluginConfig,
|
|
2390
|
+
env: process.env,
|
|
2391
|
+
shouldPromote: hasBeforeToolCallPolicy(),
|
|
2392
|
+
canUseUntrustedApprovalPolicy: configuredAppServer.start.transport !== "stdio" || isCodexAppServerApprovalPolicyAllowedByRequirements("untrusted")
|
|
2393
|
+
});
|
|
2303
2394
|
let pluginAppServer = appServer;
|
|
2304
2395
|
const nativeHookRelayEvents = resolveCodexNativeHookRelayEvents({
|
|
2305
2396
|
configuredEvents: options.nativeHookRelay?.events,
|
|
@@ -2333,6 +2424,17 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
2333
2424
|
sessionKey: sandboxSessionKey,
|
|
2334
2425
|
...startupAuthProfileId ? { authProfileId: startupAuthProfileId } : {}
|
|
2335
2426
|
};
|
|
2427
|
+
let activeSessionId = params.sessionId;
|
|
2428
|
+
let activeSessionFile = params.sessionFile;
|
|
2429
|
+
const buildActiveRunAttemptParams = () => ({
|
|
2430
|
+
...runtimeParams,
|
|
2431
|
+
sessionId: activeSessionId,
|
|
2432
|
+
sessionFile: activeSessionFile
|
|
2433
|
+
});
|
|
2434
|
+
const adoptContextEngineCompactionTranscript = (compactResult) => {
|
|
2435
|
+
if (compactResult.result?.sessionId) activeSessionId = compactResult.result.sessionId;
|
|
2436
|
+
if (compactResult.result?.sessionFile) activeSessionFile = compactResult.result.sessionFile;
|
|
2437
|
+
};
|
|
2336
2438
|
const startupAuthAccountCacheKey = await resolveCodexAppServerAuthAccountCacheKey({
|
|
2337
2439
|
authProfileId: startupAuthProfileId,
|
|
2338
2440
|
authProfileStore: params.authProfileStore,
|
|
@@ -2375,8 +2477,8 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
2375
2477
|
runId: params.runId
|
|
2376
2478
|
}
|
|
2377
2479
|
});
|
|
2378
|
-
const hadSessionFile = await pathExists(
|
|
2379
|
-
let historyMessages = await readMirroredSessionHistoryMessages(
|
|
2480
|
+
const hadSessionFile = await pathExists(activeSessionFile);
|
|
2481
|
+
let historyMessages = await readMirroredSessionHistoryMessages(activeSessionFile) ?? [];
|
|
2380
2482
|
const hookContextWindowFields = {
|
|
2381
2483
|
...params.contextWindowInfo?.tokens ? { contextTokenBudget: params.contextWindowInfo.tokens } : params.contextTokenBudget ? { contextTokenBudget: params.contextTokenBudget } : {},
|
|
2382
2484
|
...params.contextWindowInfo?.source ? { contextWindowSource: params.contextWindowInfo.source } : {},
|
|
@@ -2393,24 +2495,28 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
2393
2495
|
channelId: params.messageChannel ?? params.messageProvider ?? void 0,
|
|
2394
2496
|
...hookContextWindowFields
|
|
2395
2497
|
};
|
|
2498
|
+
const activeContextEnginePluginId = activeContextEngine ? resolveContextEngineOwnerPluginId(activeContextEngine) : void 0;
|
|
2499
|
+
const buildActiveContextEngineRuntimeContext = () => buildHarnessContextEngineRuntimeContext({
|
|
2500
|
+
attempt: buildActiveRunAttemptParams(),
|
|
2501
|
+
workspaceDir: effectiveWorkspace,
|
|
2502
|
+
agentDir,
|
|
2503
|
+
activeAgentId: sessionAgentId,
|
|
2504
|
+
contextEnginePluginId: activeContextEnginePluginId,
|
|
2505
|
+
tokenBudget: params.contextTokenBudget
|
|
2506
|
+
});
|
|
2396
2507
|
if (activeContextEngine) {
|
|
2397
2508
|
await bootstrapHarnessContextEngine({
|
|
2398
2509
|
hadSessionFile,
|
|
2399
2510
|
contextEngine: activeContextEngine,
|
|
2400
|
-
sessionId:
|
|
2511
|
+
sessionId: activeSessionId,
|
|
2401
2512
|
sessionKey: sandboxSessionKey,
|
|
2402
|
-
sessionFile:
|
|
2403
|
-
runtimeContext:
|
|
2404
|
-
attempt: runtimeParams,
|
|
2405
|
-
workspaceDir: effectiveWorkspace,
|
|
2406
|
-
agentDir,
|
|
2407
|
-
tokenBudget: params.contextTokenBudget
|
|
2408
|
-
}),
|
|
2513
|
+
sessionFile: activeSessionFile,
|
|
2514
|
+
runtimeContext: buildActiveContextEngineRuntimeContext(),
|
|
2409
2515
|
runMaintenance: runHarnessContextEngineMaintenance,
|
|
2410
2516
|
config: params.config,
|
|
2411
2517
|
warn: (message) => embeddedAgentLog.warn(message)
|
|
2412
2518
|
});
|
|
2413
|
-
historyMessages = await readMirroredSessionHistoryMessages(
|
|
2519
|
+
historyMessages = await readMirroredSessionHistoryMessages(activeSessionFile) ?? historyMessages;
|
|
2414
2520
|
}
|
|
2415
2521
|
const baseDeveloperInstructions = buildDeveloperInstructions(params);
|
|
2416
2522
|
const workspaceBootstrapContext = await buildCodexWorkspaceBootstrapContext({
|
|
@@ -2424,10 +2530,18 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
2424
2530
|
let promptText = params.prompt;
|
|
2425
2531
|
let developerInstructions = joinPresentSections(baseDeveloperInstructions, workspaceBootstrapInstructions);
|
|
2426
2532
|
let prePromptMessageCount = historyMessages.length;
|
|
2427
|
-
|
|
2533
|
+
let contextEngineProjection;
|
|
2534
|
+
const resetCodexPromptInputs = () => {
|
|
2535
|
+
promptText = params.prompt;
|
|
2536
|
+
developerInstructions = joinPresentSections(baseDeveloperInstructions, workspaceBootstrapInstructions);
|
|
2537
|
+
prePromptMessageCount = historyMessages.length;
|
|
2538
|
+
contextEngineProjection = void 0;
|
|
2539
|
+
};
|
|
2540
|
+
const applyActiveContextEngineProjection = async (decisionStartupBinding) => {
|
|
2541
|
+
if (!activeContextEngine) return;
|
|
2428
2542
|
const assembled = await assembleHarnessContextEngine({
|
|
2429
2543
|
contextEngine: activeContextEngine,
|
|
2430
|
-
sessionId:
|
|
2544
|
+
sessionId: activeSessionId,
|
|
2431
2545
|
sessionKey: sandboxSessionKey,
|
|
2432
2546
|
messages: historyMessages,
|
|
2433
2547
|
tokenBudget: params.contextTokenBudget,
|
|
@@ -2437,6 +2551,7 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
2437
2551
|
prompt: params.prompt
|
|
2438
2552
|
});
|
|
2439
2553
|
if (!assembled) throw new Error("context engine assemble returned no result");
|
|
2554
|
+
contextEngineProjection = readContextEngineThreadBootstrapProjection(assembled.contextProjection);
|
|
2440
2555
|
const projection = projectContextEngineAssemblyForCodex({
|
|
2441
2556
|
assembledMessages: assembled.messages,
|
|
2442
2557
|
originalHistoryMessages: historyMessages,
|
|
@@ -2445,11 +2560,41 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
2445
2560
|
maxRenderedContextChars: resolveCodexContextEngineProjectionMaxChars({
|
|
2446
2561
|
contextTokenBudget: params.contextTokenBudget,
|
|
2447
2562
|
reserveTokens: resolveCodexContextEngineProjectionReserveTokens({ config: params.config })
|
|
2448
|
-
})
|
|
2563
|
+
}),
|
|
2564
|
+
toolPayloadMode: contextEngineProjection ? "preserve" : "elide"
|
|
2449
2565
|
});
|
|
2450
|
-
|
|
2566
|
+
const projectionDecision = contextEngineProjection ? resolveContextEngineBootstrapProjectionDecision({
|
|
2567
|
+
startupBinding: decisionStartupBinding,
|
|
2568
|
+
expectedBinding: buildContextEngineBinding(buildActiveRunAttemptParams(), contextEngineProjection),
|
|
2569
|
+
projection: contextEngineProjection,
|
|
2570
|
+
dynamicToolsFingerprint: codexDynamicToolsFingerprint(toolBridge.specs)
|
|
2571
|
+
}) : {
|
|
2572
|
+
project: true,
|
|
2573
|
+
reason: "per-turn-projection"
|
|
2574
|
+
};
|
|
2575
|
+
embeddedAgentLog.info("codex app-server context-engine projection decision", {
|
|
2576
|
+
sessionId: params.sessionId,
|
|
2577
|
+
sessionKey: sandboxSessionKey,
|
|
2578
|
+
engineId: activeContextEngine.info.id,
|
|
2579
|
+
mode: contextEngineProjection?.mode ?? assembled.contextProjection?.mode ?? "per_turn",
|
|
2580
|
+
epoch: contextEngineProjection?.epoch,
|
|
2581
|
+
fingerprint: contextEngineProjection?.fingerprint,
|
|
2582
|
+
previousThreadId: decisionStartupBinding?.threadId,
|
|
2583
|
+
previousEpoch: decisionStartupBinding?.contextEngine?.projection?.epoch,
|
|
2584
|
+
previousFingerprint: decisionStartupBinding?.contextEngine?.projection?.fingerprint,
|
|
2585
|
+
projected: projectionDecision.project,
|
|
2586
|
+
reason: projectionDecision.reason,
|
|
2587
|
+
assembledMessages: assembled.messages.length,
|
|
2588
|
+
originalHistoryMessages: historyMessages.length,
|
|
2589
|
+
projectedPromptChars: projection.promptText.length,
|
|
2590
|
+
developerInstructionAdditionChars: projection.developerInstructionAddition?.length ?? 0
|
|
2591
|
+
});
|
|
2592
|
+
promptText = projectionDecision.project ? projection.promptText : params.prompt;
|
|
2451
2593
|
developerInstructions = joinPresentSections(baseDeveloperInstructions, workspaceBootstrapInstructions, projection.developerInstructionAddition);
|
|
2452
2594
|
prePromptMessageCount = projection.prePromptMessageCount;
|
|
2595
|
+
};
|
|
2596
|
+
if (activeContextEngine) try {
|
|
2597
|
+
await applyActiveContextEngineProjection(startupBinding);
|
|
2453
2598
|
} catch (assembleErr) {
|
|
2454
2599
|
embeddedAgentLog.warn("context engine assemble failed; using Codex baseline prompt", { error: formatErrorMessage(assembleErr) });
|
|
2455
2600
|
}
|
|
@@ -2466,13 +2611,13 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
2466
2611
|
promptText = projection.promptText;
|
|
2467
2612
|
prePromptMessageCount = projection.prePromptMessageCount;
|
|
2468
2613
|
}
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
prompt: promptText,
|
|
2614
|
+
const buildPromptFromCurrentInputs = () => resolveAgentHarnessBeforePromptBuildResult({
|
|
2615
|
+
prompt: prependCurrentTurnContext(promptText, params.currentTurnContext),
|
|
2472
2616
|
developerInstructions,
|
|
2473
2617
|
messages: historyMessages,
|
|
2474
2618
|
ctx: hookContext
|
|
2475
2619
|
});
|
|
2620
|
+
let promptBuild = await buildPromptFromCurrentInputs();
|
|
2476
2621
|
const systemPromptReport = buildCodexSystemPromptReport({
|
|
2477
2622
|
attempt: params,
|
|
2478
2623
|
sessionKey: sandboxSessionKey,
|
|
@@ -2554,9 +2699,10 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
2554
2699
|
timeoutMs: appServer.requestTimeoutMs,
|
|
2555
2700
|
signal: runAbortController.signal
|
|
2556
2701
|
});
|
|
2557
|
-
const
|
|
2702
|
+
const buildThreadLifecycleParams = () => ({
|
|
2558
2703
|
client: startupClient,
|
|
2559
|
-
params:
|
|
2704
|
+
params: buildActiveRunAttemptParams(),
|
|
2705
|
+
agentId: sessionAgentId,
|
|
2560
2706
|
cwd: effectiveWorkspace,
|
|
2561
2707
|
dynamicTools: toolBridge.specs,
|
|
2562
2708
|
appServer: pluginAppServer,
|
|
@@ -2564,6 +2710,7 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
2564
2710
|
config: threadConfig,
|
|
2565
2711
|
mcpServersFingerprint: bundleMcpThreadConfig.fingerprint,
|
|
2566
2712
|
mcpServersFingerprintEvaluated: bundleMcpThreadConfig.evaluated,
|
|
2713
|
+
contextEngineProjection,
|
|
2567
2714
|
pluginThreadConfig: pluginThreadConfigEnabled ? {
|
|
2568
2715
|
enabled: true,
|
|
2569
2716
|
inputFingerprint: pluginThreadConfigInputFingerprint,
|
|
@@ -2578,11 +2725,11 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
2578
2725
|
appCacheKey: pluginAppCacheKey
|
|
2579
2726
|
})
|
|
2580
2727
|
} : void 0
|
|
2581
|
-
};
|
|
2582
|
-
restartContextEngineCodexThread = () => startOrResumeThread(
|
|
2728
|
+
});
|
|
2729
|
+
restartContextEngineCodexThread = () => startOrResumeThread(buildThreadLifecycleParams());
|
|
2583
2730
|
return {
|
|
2584
2731
|
client: startupClient,
|
|
2585
|
-
thread: await startOrResumeThread(
|
|
2732
|
+
thread: await startOrResumeThread(buildThreadLifecycleParams())
|
|
2586
2733
|
};
|
|
2587
2734
|
};
|
|
2588
2735
|
for (let attempt = 1; attempt <= CODEX_APP_SERVER_STARTUP_CONNECTION_CLOSE_MAX_ATTEMPTS; attempt += 1) try {
|
|
@@ -2916,6 +3063,9 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
2916
3063
|
}
|
|
2917
3064
|
if (isCurrentTurnNotification) updateActiveTurnItemIds(notification, activeTurnItemIds);
|
|
2918
3065
|
const unblockedAssistantCompletionRelease = isCurrentTurnNotification && turnAssistantCompletionIdleWatchArmed && notification.method === "item/completed" && activeTurnItemIds.size === 0;
|
|
3066
|
+
const trackedDynamicToolCompletion = isTrackedOpenClawDynamicToolCompletionNotification(notification, activeOpenClawDynamicToolCallIds);
|
|
3067
|
+
const rawToolOutputCompletion = isRawToolOutputCompletionNotification(notification);
|
|
3068
|
+
const shouldRearmCompletionIdleWatchAfterLastCurrentTurnItem = isCurrentTurnNotification && notification.method === "item/completed" && activeTurnItemIds.size === 0 && !trackedDynamicToolCompletion && !isCompletedAssistantNotification(notification);
|
|
2919
3069
|
if (isCurrentTurnNotification && notification.method === "error") {
|
|
2920
3070
|
if (isRetryableErrorNotification(notification.params)) disarmTurnCompletionIdleWatch();
|
|
2921
3071
|
else armTurnCompletionIdleWatch({ pinnedByTerminalError: true });
|
|
@@ -2923,11 +3073,14 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
2923
3073
|
} else if (isTurnCompletion) disarmTurnAssistantCompletionIdleWatch();
|
|
2924
3074
|
else if (isCurrentTurnNotification && isCompletedAssistantNotification(notification)) armTurnAssistantCompletionIdleWatch(describeNotificationActivity(notification));
|
|
2925
3075
|
else if (unblockedAssistantCompletionRelease) armTurnAssistantCompletionIdleWatch(describeNotificationActivity(notification));
|
|
3076
|
+
else if (shouldRearmCompletionIdleWatchAfterLastCurrentTurnItem) armTurnCompletionIdleWatch();
|
|
3077
|
+
else if (isCurrentTurnNotification && rawToolOutputCompletion) armTurnCompletionIdleWatch();
|
|
2926
3078
|
else if (isCurrentTurnNotification && shouldDisarmAssistantCompletionIdleWatch(notification)) disarmTurnAssistantCompletionIdleWatch();
|
|
2927
|
-
if (turnCompletionIdleWatchArmed && !turnCompletionIdleWatchPinnedByTerminalError && notification.method !== "turn/completed" && isCurrentTurnNotification && !
|
|
3079
|
+
if (turnCompletionIdleWatchArmed && !turnCompletionIdleWatchPinnedByTerminalError && notification.method !== "turn/completed" && isCurrentTurnNotification && !trackedDynamicToolCompletion && !rawToolOutputCompletion && !shouldRearmCompletionIdleWatchAfterLastCurrentTurnItem) disarmTurnCompletionIdleWatch();
|
|
2928
3080
|
const isTurnAbortMarker = isCurrentTurnNotification && isCodexTurnAbortMarkerNotification(notification, { currentPromptText: promptBuild.prompt });
|
|
2929
3081
|
const isTurnTerminal = isTurnCompletion || isTurnAbortMarker;
|
|
2930
3082
|
try {
|
|
3083
|
+
await waitForCodexNotificationDispatchTurn();
|
|
2931
3084
|
await projector.handleNotification(notification);
|
|
2932
3085
|
} catch (error) {
|
|
2933
3086
|
embeddedAgentLog.debug("codex app-server projector notification threw", {
|
|
@@ -2947,6 +3100,11 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
2947
3100
|
}
|
|
2948
3101
|
};
|
|
2949
3102
|
const enqueueNotification = (notification) => {
|
|
3103
|
+
if (!projector || !turnId) {
|
|
3104
|
+
userInputBridge?.handleNotification(notification);
|
|
3105
|
+
pendingNotifications.push(notification);
|
|
3106
|
+
return Promise.resolve();
|
|
3107
|
+
}
|
|
2950
3108
|
notificationQueue = notificationQueue.then(() => handleNotification(notification), () => handleNotification(notification));
|
|
2951
3109
|
return notificationQueue;
|
|
2952
3110
|
};
|
|
@@ -3079,7 +3237,76 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
3079
3237
|
touchTurnCompletionActivity(`request:${request.method}:response`, { arm: armCompletionWatchOnResponse });
|
|
3080
3238
|
}
|
|
3081
3239
|
});
|
|
3082
|
-
const
|
|
3240
|
+
const forceContextEngineCompactionForCodexOverflow = async (error) => {
|
|
3241
|
+
if (!activeContextEngine?.info.ownsCompaction) return false;
|
|
3242
|
+
embeddedAgentLog.warn("codex app-server context-engine turn overflowed; forcing context-engine compaction", {
|
|
3243
|
+
sessionId: activeSessionId,
|
|
3244
|
+
sessionKey: sandboxSessionKey,
|
|
3245
|
+
threadId: thread.threadId,
|
|
3246
|
+
engineId: activeContextEngine.info.id,
|
|
3247
|
+
tokenBudget: params.contextTokenBudget,
|
|
3248
|
+
error: formatErrorMessage(error)
|
|
3249
|
+
});
|
|
3250
|
+
try {
|
|
3251
|
+
const runtimeContext = buildActiveContextEngineRuntimeContext();
|
|
3252
|
+
const overflowTokenCount = params.contextTokenBudget ?? params.contextWindowInfo?.tokens;
|
|
3253
|
+
const compactResult = await activeContextEngine.compact({
|
|
3254
|
+
sessionId: activeSessionId,
|
|
3255
|
+
sessionKey: sandboxSessionKey,
|
|
3256
|
+
sessionFile: activeSessionFile,
|
|
3257
|
+
tokenBudget: params.contextTokenBudget,
|
|
3258
|
+
force: true,
|
|
3259
|
+
...overflowTokenCount ? { currentTokenCount: overflowTokenCount } : {},
|
|
3260
|
+
compactionTarget: "threshold",
|
|
3261
|
+
runtimeContext: overflowTokenCount ? {
|
|
3262
|
+
...runtimeContext,
|
|
3263
|
+
currentTokenCount: overflowTokenCount
|
|
3264
|
+
} : runtimeContext
|
|
3265
|
+
});
|
|
3266
|
+
embeddedAgentLog.info("codex app-server context-engine forced compaction result", {
|
|
3267
|
+
sessionId: activeSessionId,
|
|
3268
|
+
sessionKey: sandboxSessionKey,
|
|
3269
|
+
engineId: activeContextEngine.info.id,
|
|
3270
|
+
ok: compactResult.ok,
|
|
3271
|
+
compacted: compactResult.compacted,
|
|
3272
|
+
reason: compactResult.reason,
|
|
3273
|
+
tokensBefore: compactResult.result?.tokensBefore,
|
|
3274
|
+
tokensAfter: compactResult.result?.tokensAfter
|
|
3275
|
+
});
|
|
3276
|
+
if (!compactResult.ok || !compactResult.compacted) return false;
|
|
3277
|
+
adoptContextEngineCompactionTranscript(compactResult);
|
|
3278
|
+
const maintenanceRuntimeContext = buildActiveContextEngineRuntimeContext();
|
|
3279
|
+
await runHarnessContextEngineMaintenance({
|
|
3280
|
+
contextEngine: activeContextEngine,
|
|
3281
|
+
sessionId: activeSessionId,
|
|
3282
|
+
sessionKey: sandboxSessionKey,
|
|
3283
|
+
sessionFile: activeSessionFile,
|
|
3284
|
+
reason: "compaction",
|
|
3285
|
+
runtimeContext: maintenanceRuntimeContext,
|
|
3286
|
+
config: params.config
|
|
3287
|
+
});
|
|
3288
|
+
return true;
|
|
3289
|
+
} catch (compactErr) {
|
|
3290
|
+
embeddedAgentLog.warn("codex app-server context-engine forced compaction failed", {
|
|
3291
|
+
sessionId: params.sessionId,
|
|
3292
|
+
sessionKey: sandboxSessionKey,
|
|
3293
|
+
engineId: activeContextEngine.info.id,
|
|
3294
|
+
error: formatErrorMessage(compactErr)
|
|
3295
|
+
});
|
|
3296
|
+
return false;
|
|
3297
|
+
}
|
|
3298
|
+
};
|
|
3299
|
+
const rebuildPromptAfterContextEngineCompaction = async () => {
|
|
3300
|
+
historyMessages = await readMirroredSessionHistoryMessages(activeSessionFile) ?? historyMessages;
|
|
3301
|
+
resetCodexPromptInputs();
|
|
3302
|
+
try {
|
|
3303
|
+
await applyActiveContextEngineProjection(void 0);
|
|
3304
|
+
} catch (assembleErr) {
|
|
3305
|
+
embeddedAgentLog.warn("context engine assemble failed after forced compaction; using Codex baseline prompt", { error: formatErrorMessage(assembleErr) });
|
|
3306
|
+
}
|
|
3307
|
+
promptBuild = await buildPromptFromCurrentInputs();
|
|
3308
|
+
};
|
|
3309
|
+
const buildLlmInputEvent = () => ({
|
|
3083
3310
|
runId: params.runId,
|
|
3084
3311
|
sessionId: params.sessionId,
|
|
3085
3312
|
provider: params.provider,
|
|
@@ -3088,12 +3315,11 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
3088
3315
|
prompt: promptBuild.prompt,
|
|
3089
3316
|
historyMessages,
|
|
3090
3317
|
imagesCount: params.images?.length ?? 0
|
|
3091
|
-
};
|
|
3092
|
-
const
|
|
3093
|
-
|
|
3094
|
-
|
|
3095
|
-
|
|
3096
|
-
}];
|
|
3318
|
+
});
|
|
3319
|
+
const buildTurnStartFailureMessages = () => [...historyMessages, buildCodexUserPromptMessage({
|
|
3320
|
+
...params,
|
|
3321
|
+
prompt: promptBuild.prompt
|
|
3322
|
+
})];
|
|
3097
3323
|
let turn;
|
|
3098
3324
|
const startCodexTurn = async () => assertCodexTurnStartResponse(await client.request("turn/start", buildTurnStartParams(params, {
|
|
3099
3325
|
threadId: thread.threadId,
|
|
@@ -3106,7 +3332,7 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
3106
3332
|
}));
|
|
3107
3333
|
try {
|
|
3108
3334
|
runAgentHarnessLlmInputHook({
|
|
3109
|
-
event:
|
|
3335
|
+
event: buildLlmInputEvent(),
|
|
3110
3336
|
ctx: hookContext
|
|
3111
3337
|
});
|
|
3112
3338
|
emitCodexAppServerEvent(params, {
|
|
@@ -3128,7 +3354,11 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
3128
3354
|
threadId: thread.threadId,
|
|
3129
3355
|
error: formatErrorMessage(turnStartError)
|
|
3130
3356
|
});
|
|
3131
|
-
|
|
3357
|
+
const preRetrySessionFile = activeSessionFile;
|
|
3358
|
+
const compactedForRetry = await forceContextEngineCompactionForCodexOverflow(turnStartError);
|
|
3359
|
+
await clearCodexAppServerBinding(preRetrySessionFile);
|
|
3360
|
+
if (activeSessionFile !== preRetrySessionFile) await clearCodexAppServerBinding(activeSessionFile);
|
|
3361
|
+
if (compactedForRetry) await rebuildPromptAfterContextEngineCompaction();
|
|
3132
3362
|
thread = await restartContextEngineCodexThread();
|
|
3133
3363
|
emitCodexAppServerEvent(params, {
|
|
3134
3364
|
stream: "codex_app_server.lifecycle",
|
|
@@ -3182,7 +3412,7 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
3182
3412
|
});
|
|
3183
3413
|
runAgentHarnessAgentEndHook({
|
|
3184
3414
|
event: {
|
|
3185
|
-
messages:
|
|
3415
|
+
messages: buildTurnStartFailureMessages(),
|
|
3186
3416
|
success: false,
|
|
3187
3417
|
error: turnStartErrorMessage,
|
|
3188
3418
|
durationMs: Date.now() - attemptStartedAt
|
|
@@ -3211,7 +3441,7 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
3211
3441
|
return buildCodexTurnStartFailureResult({
|
|
3212
3442
|
params,
|
|
3213
3443
|
message: usageLimitError.message,
|
|
3214
|
-
messagesSnapshot:
|
|
3444
|
+
messagesSnapshot: buildTurnStartFailureMessages(),
|
|
3215
3445
|
systemPromptReport
|
|
3216
3446
|
});
|
|
3217
3447
|
}
|
|
@@ -3237,6 +3467,8 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
3237
3467
|
projector = new CodexAppServerEventProjector(params, thread.threadId, activeTurnId, { nativePostToolUseRelayEnabled: nativeHookRelay?.allowedEvents.includes("post_tool_use") === true });
|
|
3238
3468
|
emitLifecycleStart();
|
|
3239
3469
|
const activeProjector = projector;
|
|
3470
|
+
turnTerminalIdleWatchArmed = true;
|
|
3471
|
+
touchTurnCompletionActivity("turn:start", { arm: true });
|
|
3240
3472
|
for (const notification of pendingNotifications.splice(0)) await enqueueNotification(notification);
|
|
3241
3473
|
if (!completed && isTerminalTurnStatus(turn.turn.status)) await enqueueNotification({
|
|
3242
3474
|
method: "turn/completed",
|
|
@@ -3263,8 +3495,6 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
3263
3495
|
abort: () => runAbortController.abort("aborted")
|
|
3264
3496
|
};
|
|
3265
3497
|
setActiveEmbeddedRun(params.sessionId, handle, params.sessionKey);
|
|
3266
|
-
turnTerminalIdleWatchArmed = true;
|
|
3267
|
-
touchTurnCompletionActivity("turn:start");
|
|
3268
3498
|
const timeout = setTimeout(() => {
|
|
3269
3499
|
timedOut = true;
|
|
3270
3500
|
projector?.markTimedOut();
|
|
@@ -3342,22 +3572,25 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
3342
3572
|
...finalAborted ? { aborted: true } : {}
|
|
3343
3573
|
});
|
|
3344
3574
|
if (activeContextEngine) {
|
|
3345
|
-
const
|
|
3575
|
+
const activeContextEnginePluginId = resolveContextEngineOwnerPluginId(activeContextEngine);
|
|
3576
|
+
const finalMessages = await readMirroredSessionHistoryMessages(activeSessionFile) ?? historyMessages.concat(result.messagesSnapshot);
|
|
3346
3577
|
await finalizeHarnessContextEngineTurn({
|
|
3347
3578
|
contextEngine: activeContextEngine,
|
|
3348
3579
|
promptError: Boolean(finalPromptError),
|
|
3349
3580
|
aborted: finalAborted,
|
|
3350
3581
|
yieldAborted: Boolean(result.yieldDetected),
|
|
3351
|
-
sessionIdUsed:
|
|
3582
|
+
sessionIdUsed: activeSessionId,
|
|
3352
3583
|
sessionKey: sandboxSessionKey,
|
|
3353
|
-
sessionFile:
|
|
3584
|
+
sessionFile: activeSessionFile,
|
|
3354
3585
|
messagesSnapshot: finalMessages,
|
|
3355
3586
|
prePromptMessageCount,
|
|
3356
3587
|
tokenBudget: params.contextTokenBudget,
|
|
3357
3588
|
runtimeContext: buildHarnessContextEngineRuntimeContextFromUsage({
|
|
3358
|
-
attempt:
|
|
3589
|
+
attempt: buildActiveRunAttemptParams(),
|
|
3359
3590
|
workspaceDir: effectiveWorkspace,
|
|
3360
3591
|
agentDir,
|
|
3592
|
+
activeAgentId: sessionAgentId,
|
|
3593
|
+
contextEnginePluginId: activeContextEnginePluginId,
|
|
3361
3594
|
tokenBudget: params.contextTokenBudget,
|
|
3362
3595
|
lastCallUsage: result.attemptUsage,
|
|
3363
3596
|
promptCache: result.promptCache
|
|
@@ -3650,14 +3883,12 @@ function resolveOpenClawCodingToolsSessionKeys(params, sandboxSessionKey) {
|
|
|
3650
3883
|
runSessionKey: params.sessionKey && params.sessionKey !== sandboxSessionKey ? params.sessionKey : void 0
|
|
3651
3884
|
};
|
|
3652
3885
|
}
|
|
3653
|
-
|
|
3886
|
+
function buildOpenClawCodingToolsOptions(input) {
|
|
3654
3887
|
const { params } = input;
|
|
3655
|
-
if (params.disableTools || !supportsModelTools(params.model)) return [];
|
|
3656
3888
|
const modelHasVision = params.model.input?.includes("image") ?? false;
|
|
3657
3889
|
const agentDir = params.agentDir ?? resolveAgentDir$1(params.config ?? {}, input.sessionAgentId);
|
|
3658
|
-
const createOpenClawCodingTools = openClawCodingToolsFactoryForTests ?? (await import("openclaw/plugin-sdk/agent-harness")).createOpenClawCodingTools;
|
|
3659
3890
|
const sessionKeys = resolveOpenClawCodingToolsSessionKeys(params, input.sandboxSessionKey);
|
|
3660
|
-
|
|
3891
|
+
return {
|
|
3661
3892
|
agentId: input.sessionAgentId,
|
|
3662
3893
|
...buildEmbeddedAttemptToolRunContext(params),
|
|
3663
3894
|
exec: {
|
|
@@ -3721,8 +3952,15 @@ async function buildDynamicTools(input) {
|
|
|
3721
3952
|
});
|
|
3722
3953
|
input.runAbortController.abort("sessions_yield");
|
|
3723
3954
|
}
|
|
3724
|
-
}
|
|
3725
|
-
|
|
3955
|
+
};
|
|
3956
|
+
}
|
|
3957
|
+
async function buildDynamicTools(input) {
|
|
3958
|
+
const { params } = input;
|
|
3959
|
+
if (params.disableTools || !supportsModelTools(params.model)) return [];
|
|
3960
|
+
const createOpenClawCodingTools = openClawCodingToolsFactoryForTests ?? (await import("openclaw/plugin-sdk/agent-harness")).createOpenClawCodingTools;
|
|
3961
|
+
const toolOptions = buildOpenClawCodingToolsOptions(input);
|
|
3962
|
+
const filteredTools = filterCodexDynamicToolsForAllowlist(filterToolsForVisionInputs(filterCodexDynamicTools(createOpenClawCodingTools(toolOptions), input.pluginConfig), {
|
|
3963
|
+
modelHasVision: toolOptions.modelHasVision ?? false,
|
|
3726
3964
|
hasInboundImages: (params.images?.length ?? 0) > 0
|
|
3727
3965
|
}), includeForcedMessageToolAllow(params.toolsAllow, params));
|
|
3728
3966
|
return normalizeAgentRuntimeTools({
|
|
@@ -3759,6 +3997,45 @@ function shouldProjectMirroredHistoryForCodexStart(params) {
|
|
|
3759
3997
|
next: params.dynamicToolsFingerprint
|
|
3760
3998
|
});
|
|
3761
3999
|
}
|
|
4000
|
+
function readContextEngineThreadBootstrapProjection(projection) {
|
|
4001
|
+
if (projection?.mode !== "thread_bootstrap") return;
|
|
4002
|
+
const epoch = projection.epoch?.trim();
|
|
4003
|
+
if (!epoch) {
|
|
4004
|
+
embeddedAgentLog.warn("context engine requested Codex thread-bootstrap projection without an epoch; using per-turn projection");
|
|
4005
|
+
return;
|
|
4006
|
+
}
|
|
4007
|
+
const fingerprint = projection.fingerprint?.trim();
|
|
4008
|
+
return {
|
|
4009
|
+
mode: "thread_bootstrap",
|
|
4010
|
+
epoch,
|
|
4011
|
+
...fingerprint ? { fingerprint } : {}
|
|
4012
|
+
};
|
|
4013
|
+
}
|
|
4014
|
+
function resolveContextEngineBootstrapProjectionDecision(params) {
|
|
4015
|
+
const bindingProjection = params.startupBinding?.contextEngine?.projection;
|
|
4016
|
+
if (!params.startupBinding?.threadId || !bindingProjection) return {
|
|
4017
|
+
project: true,
|
|
4018
|
+
reason: !params.startupBinding?.threadId ? "missing-thread-binding" : "missing-projection-binding"
|
|
4019
|
+
};
|
|
4020
|
+
if (!params.expectedBinding || !isContextEngineBindingCompatible(params.startupBinding.contextEngine, params.expectedBinding)) return {
|
|
4021
|
+
project: true,
|
|
4022
|
+
reason: "context-engine-binding-mismatch"
|
|
4023
|
+
};
|
|
4024
|
+
if (!areCodexDynamicToolFingerprintsCompatible({
|
|
4025
|
+
previous: params.startupBinding.dynamicToolsFingerprint,
|
|
4026
|
+
next: params.dynamicToolsFingerprint
|
|
4027
|
+
})) return {
|
|
4028
|
+
project: true,
|
|
4029
|
+
reason: "dynamic-tools-mismatch"
|
|
4030
|
+
};
|
|
4031
|
+
return bindingProjection.mode !== "thread_bootstrap" || bindingProjection.epoch !== params.projection.epoch || bindingProjection.fingerprint !== params.projection.fingerprint ? {
|
|
4032
|
+
project: true,
|
|
4033
|
+
reason: "projection-mismatch"
|
|
4034
|
+
} : {
|
|
4035
|
+
project: false,
|
|
4036
|
+
reason: "matching-thread-bootstrap-binding"
|
|
4037
|
+
};
|
|
4038
|
+
}
|
|
3762
4039
|
async function withCodexStartupTimeout(params) {
|
|
3763
4040
|
if (params.signal.aborted) throw new Error("codex app-server startup aborted");
|
|
3764
4041
|
let timeout;
|
|
@@ -3959,6 +4236,11 @@ function isTrackedOpenClawDynamicToolCompletionNotification(notification, active
|
|
|
3959
4236
|
const itemType = item ? readString(item, "type") : void 0;
|
|
3960
4237
|
return itemType === void 0 || itemType === "dynamicToolCall";
|
|
3961
4238
|
}
|
|
4239
|
+
function isRawToolOutputCompletionNotification(notification) {
|
|
4240
|
+
if (notification.method !== "rawResponseItem/completed" || !isJsonObject(notification.params)) return false;
|
|
4241
|
+
const item = isJsonObject(notification.params.item) ? notification.params.item : void 0;
|
|
4242
|
+
return item ? readString(item, "type") === "custom_tool_call_output" : false;
|
|
4243
|
+
}
|
|
3962
4244
|
function readRawAssistantTextPreview(item) {
|
|
3963
4245
|
if (readString(item, "role") !== "assistant" || !Array.isArray(item.content)) return;
|
|
3964
4246
|
const text = item.content.flatMap((content) => {
|
|
@@ -4244,6 +4526,11 @@ function prependCurrentTurnContext(prompt, context) {
|
|
|
4244
4526
|
const text = context?.text.trim();
|
|
4245
4527
|
return text ? [text, prompt].filter(Boolean).join("\n\n") : prompt;
|
|
4246
4528
|
}
|
|
4529
|
+
function waitForCodexNotificationDispatchTurn() {
|
|
4530
|
+
return new Promise((resolve) => {
|
|
4531
|
+
setImmediate(resolve);
|
|
4532
|
+
});
|
|
4533
|
+
}
|
|
4247
4534
|
function handleApprovalRequest(params) {
|
|
4248
4535
|
return handleCodexAppServerApprovalRequest({
|
|
4249
4536
|
method: params.method,
|