yepanywhere 0.6.0 → 0.6.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/bundled/@yep-anywhere/shared/dist/app-types.d.ts +25 -0
- package/bundled/@yep-anywhere/shared/dist/app-types.d.ts.map +1 -1
- package/bundled/@yep-anywhere/shared/dist/app-types.js.map +1 -1
- package/bundled/@yep-anywhere/shared/dist/codex-schema/session.d.ts +179 -14
- package/bundled/@yep-anywhere/shared/dist/codex-schema/session.d.ts.map +1 -1
- package/bundled/@yep-anywhere/shared/dist/codex-schema/session.js +89 -0
- package/bundled/@yep-anywhere/shared/dist/codex-schema/session.js.map +1 -1
- package/bundled/@yep-anywhere/shared/dist/codex-tool-correlation.d.ts +25 -0
- package/bundled/@yep-anywhere/shared/dist/codex-tool-correlation.d.ts.map +1 -0
- package/bundled/@yep-anywhere/shared/dist/codex-tool-correlation.js +52 -0
- package/bundled/@yep-anywhere/shared/dist/codex-tool-correlation.js.map +1 -0
- package/bundled/@yep-anywhere/shared/dist/codex-web-run.d.ts +46 -0
- package/bundled/@yep-anywhere/shared/dist/codex-web-run.d.ts.map +1 -0
- package/bundled/@yep-anywhere/shared/dist/codex-web-run.js +14 -0
- package/bundled/@yep-anywhere/shared/dist/codex-web-run.js.map +1 -0
- package/bundled/@yep-anywhere/shared/dist/git-status.d.ts +29 -6
- package/bundled/@yep-anywhere/shared/dist/git-status.d.ts.map +1 -1
- package/bundled/@yep-anywhere/shared/dist/git-status.js +1 -6
- package/bundled/@yep-anywhere/shared/dist/git-status.js.map +1 -1
- package/bundled/@yep-anywhere/shared/dist/index.d.ts +7 -2
- package/bundled/@yep-anywhere/shared/dist/index.d.ts.map +1 -1
- package/bundled/@yep-anywhere/shared/dist/index.js +2 -0
- package/bundled/@yep-anywhere/shared/dist/index.js.map +1 -1
- package/bundled/@yep-anywhere/shared/dist/server-capabilities.d.ts +248 -0
- package/bundled/@yep-anywhere/shared/dist/server-capabilities.d.ts.map +1 -0
- package/bundled/@yep-anywhere/shared/dist/server-capabilities.js +251 -0
- package/bundled/@yep-anywhere/shared/dist/server-capabilities.js.map +1 -0
- package/bundled/@yep-anywhere/shared/dist/tool-display-actions.d.ts +26 -0
- package/bundled/@yep-anywhere/shared/dist/tool-display-actions.d.ts.map +1 -0
- package/bundled/@yep-anywhere/shared/dist/tool-display-actions.js +9 -0
- package/bundled/@yep-anywhere/shared/dist/tool-display-actions.js.map +1 -0
- package/bundled/@yep-anywhere/shared/package.json +1 -1
- package/client-dist/assets/de-BNhVdIq4.js +6 -0
- package/client-dist/assets/es-Csn9n24J.js +6 -0
- package/client-dist/assets/fr-DKx4tSpo.js +6 -0
- package/client-dist/assets/index-1y2h7U7U.js +582 -0
- package/client-dist/assets/index-Cn_ZDP6u.css +1 -0
- package/client-dist/assets/ja-DAkhkwQZ.js +6 -0
- package/client-dist/assets/zh-CN-B7lY0cc6.js +6 -0
- package/client-dist/index.html +2 -2
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js.map +1 -1
- package/dist/codex/codeModeExec.d.ts +30 -0
- package/dist/codex/codeModeExec.d.ts.map +1 -0
- package/dist/codex/codeModeExec.js +419 -0
- package/dist/codex/codeModeExec.js.map +1 -0
- package/dist/codex/displayActions.d.ts +48 -0
- package/dist/codex/displayActions.d.ts.map +1 -0
- package/dist/codex/displayActions.js +674 -0
- package/dist/codex/displayActions.js.map +1 -0
- package/dist/codex/normalization.d.ts +10 -7
- package/dist/codex/normalization.d.ts.map +1 -1
- package/dist/codex/normalization.js +179 -502
- package/dist/codex/normalization.js.map +1 -1
- package/dist/codex/webRun.d.ts +42 -0
- package/dist/codex/webRun.d.ts.map +1 -0
- package/dist/codex/webRun.js +199 -0
- package/dist/codex/webRun.js.map +1 -0
- package/dist/indexes/SessionIndexService.d.ts +1 -1
- package/dist/indexes/SessionIndexService.d.ts.map +1 -1
- package/dist/indexes/SessionIndexService.js +16 -4
- package/dist/indexes/SessionIndexService.js.map +1 -1
- package/dist/routes/git-status.d.ts.map +1 -1
- package/dist/routes/git-status.js +70 -0
- package/dist/routes/git-status.js.map +1 -1
- package/dist/routes/project-queue.d.ts.map +1 -1
- package/dist/routes/project-queue.js.map +1 -1
- package/dist/routes/public-shares.d.ts +1 -1
- package/dist/routes/public-shares.d.ts.map +1 -1
- package/dist/routes/public-shares.js +4 -6
- package/dist/routes/public-shares.js.map +1 -1
- package/dist/routes/session-metadata-patch.d.ts +24 -0
- package/dist/routes/session-metadata-patch.d.ts.map +1 -0
- package/dist/routes/session-metadata-patch.js +119 -0
- package/dist/routes/session-metadata-patch.js.map +1 -0
- package/dist/routes/session-project-routing.d.ts +25 -0
- package/dist/routes/session-project-routing.d.ts.map +1 -0
- package/dist/routes/session-project-routing.js +32 -0
- package/dist/routes/session-project-routing.js.map +1 -0
- package/dist/routes/session-provider-resolution.d.ts +28 -0
- package/dist/routes/session-provider-resolution.d.ts.map +1 -0
- package/dist/routes/session-provider-resolution.js +22 -0
- package/dist/routes/session-provider-resolution.js.map +1 -0
- package/dist/routes/session-queue-summaries.d.ts +21 -0
- package/dist/routes/session-queue-summaries.d.ts.map +1 -0
- package/dist/routes/session-queue-summaries.js +79 -0
- package/dist/routes/session-queue-summaries.js.map +1 -0
- package/dist/routes/session-recovered-queue.d.ts +43 -0
- package/dist/routes/session-recovered-queue.d.ts.map +1 -0
- package/dist/routes/session-recovered-queue.js +132 -0
- package/dist/routes/session-recovered-queue.js.map +1 -0
- package/dist/routes/session-thinking-options.d.ts +12 -0
- package/dist/routes/session-thinking-options.d.ts.map +1 -0
- package/dist/routes/session-thinking-options.js +7 -0
- package/dist/routes/session-thinking-options.js.map +1 -0
- package/dist/routes/sessions.d.ts.map +1 -1
- package/dist/routes/sessions.js +110 -409
- package/dist/routes/sessions.js.map +1 -1
- package/dist/routes/settings-parsers.d.ts +37 -0
- package/dist/routes/settings-parsers.d.ts.map +1 -0
- package/dist/routes/settings-parsers.js +896 -0
- package/dist/routes/settings-parsers.js.map +1 -0
- package/dist/routes/settings.d.ts.map +1 -1
- package/dist/routes/settings.js +4 -894
- package/dist/routes/settings.js.map +1 -1
- package/dist/routes/version.d.ts +0 -2
- package/dist/routes/version.d.ts.map +1 -1
- package/dist/routes/version.js +8 -10
- package/dist/routes/version.js.map +1 -1
- package/dist/sdk/cli-detection.d.ts +15 -1
- package/dist/sdk/cli-detection.d.ts.map +1 -1
- package/dist/sdk/cli-detection.js +159 -28
- package/dist/sdk/cli-detection.js.map +1 -1
- package/dist/sdk/messageQueue.d.ts +5 -0
- package/dist/sdk/messageQueue.d.ts.map +1 -1
- package/dist/sdk/messageQueue.js +21 -0
- package/dist/sdk/messageQueue.js.map +1 -1
- package/dist/sdk/providers/codex-model-catalog.d.ts +34 -0
- package/dist/sdk/providers/codex-model-catalog.d.ts.map +1 -0
- package/dist/sdk/providers/codex-model-catalog.js +378 -0
- package/dist/sdk/providers/codex-model-catalog.js.map +1 -0
- package/dist/sdk/providers/codex-notification-guards.d.ts +15 -0
- package/dist/sdk/providers/codex-notification-guards.d.ts.map +1 -0
- package/dist/sdk/providers/codex-notification-guards.js +159 -0
- package/dist/sdk/providers/codex-notification-guards.js.map +1 -0
- package/dist/sdk/providers/codex-protocol/generated/ImageGenerationItem.d.ts +9 -0
- package/dist/sdk/providers/codex-protocol/generated/ImageGenerationItem.d.ts.map +1 -0
- package/dist/sdk/providers/codex-protocol/generated/ImageGenerationItem.js +3 -0
- package/dist/sdk/providers/codex-protocol/generated/ImageGenerationItem.js.map +1 -0
- package/dist/sdk/providers/codex-protocol/generated/MultiAgentMode.d.ts +5 -5
- package/dist/sdk/providers/codex-protocol/generated/MultiAgentMode.d.ts.map +1 -1
- package/dist/sdk/providers/codex-protocol/generated/ResponseItem.d.ts +1 -0
- package/dist/sdk/providers/codex-protocol/generated/ResponseItem.d.ts.map +1 -1
- package/dist/sdk/providers/codex-protocol/generated/ThreadId.d.ts +5 -0
- package/dist/sdk/providers/codex-protocol/generated/ThreadId.d.ts.map +1 -1
- package/dist/sdk/providers/codex-protocol/generated/WebSearchItem.d.ts +7 -0
- package/dist/sdk/providers/codex-protocol/generated/WebSearchItem.d.ts.map +1 -0
- package/dist/sdk/providers/codex-protocol/generated/WebSearchItem.js +3 -0
- package/dist/sdk/providers/codex-protocol/generated/WebSearchItem.js.map +1 -0
- package/dist/sdk/providers/codex-protocol/generated/v2/AskForApproval.d.ts +1 -1
- package/dist/sdk/providers/codex-protocol/generated/v2/AskForApproval.d.ts.map +1 -1
- package/dist/sdk/providers/codex-protocol/generated/v2/CapabilityRootLocation.d.ts +3 -0
- package/dist/sdk/providers/codex-protocol/generated/v2/CapabilityRootLocation.d.ts.map +1 -1
- package/dist/sdk/providers/codex-protocol/generated/v2/CodexErrorInfo.d.ts +1 -1
- package/dist/sdk/providers/codex-protocol/generated/v2/CodexErrorInfo.d.ts.map +1 -1
- package/dist/sdk/providers/codex-protocol/generated/v2/McpToolCallAppContext.d.ts +3 -0
- package/dist/sdk/providers/codex-protocol/generated/v2/McpToolCallAppContext.d.ts.map +1 -1
- package/dist/sdk/providers/codex-protocol/generated/v2/Thread.d.ts +13 -0
- package/dist/sdk/providers/codex-protocol/generated/v2/Thread.d.ts.map +1 -1
- package/dist/sdk/providers/codex-protocol/generated/v2/ThreadExtra.d.ts +5 -0
- package/dist/sdk/providers/codex-protocol/generated/v2/ThreadExtra.d.ts.map +1 -0
- package/dist/sdk/providers/codex-protocol/generated/v2/ThreadExtra.js +3 -0
- package/dist/sdk/providers/codex-protocol/generated/v2/ThreadExtra.js.map +1 -0
- package/dist/sdk/providers/codex-protocol/generated/v2/ThreadForkParams.d.ts +7 -0
- package/dist/sdk/providers/codex-protocol/generated/v2/ThreadForkParams.d.ts.map +1 -1
- package/dist/sdk/providers/codex-protocol/generated/v2/ThreadHistoryMode.d.ts +2 -0
- package/dist/sdk/providers/codex-protocol/generated/v2/ThreadHistoryMode.d.ts.map +1 -0
- package/dist/sdk/providers/codex-protocol/generated/v2/ThreadHistoryMode.js +3 -0
- package/dist/sdk/providers/codex-protocol/generated/v2/ThreadHistoryMode.js.map +1 -0
- package/dist/sdk/providers/codex-protocol/generated/v2/ThreadItem.d.ts +5 -13
- package/dist/sdk/providers/codex-protocol/generated/v2/ThreadItem.d.ts.map +1 -1
- package/dist/sdk/providers/codex-protocol/generated/v2/ThreadRollbackParams.d.ts +3 -0
- package/dist/sdk/providers/codex-protocol/generated/v2/ThreadRollbackParams.d.ts.map +1 -1
- package/dist/sdk/providers/codex-protocol/generated/v2/ThreadStartParams.d.ts +10 -0
- package/dist/sdk/providers/codex-protocol/generated/v2/ThreadStartParams.d.ts.map +1 -1
- package/dist/sdk/providers/codex-protocol/generated/v2/Turn.d.ts +3 -0
- package/dist/sdk/providers/codex-protocol/generated/v2/Turn.d.ts.map +1 -1
- package/dist/sdk/providers/codex-summary-helpers.d.ts +41 -0
- package/dist/sdk/providers/codex-summary-helpers.d.ts.map +1 -0
- package/dist/sdk/providers/codex-summary-helpers.js +207 -0
- package/dist/sdk/providers/codex-summary-helpers.js.map +1 -0
- package/dist/sdk/providers/codex.d.ts +0 -25
- package/dist/sdk/providers/codex.d.ts.map +1 -1
- package/dist/sdk/providers/codex.js +160 -703
- package/dist/sdk/providers/codex.js.map +1 -1
- package/dist/sdk/providers/opencode-models.d.ts +17 -0
- package/dist/sdk/providers/opencode-models.d.ts.map +1 -0
- package/dist/sdk/providers/opencode-models.js +83 -0
- package/dist/sdk/providers/opencode-models.js.map +1 -0
- package/dist/sdk/providers/opencode.d.ts +1 -9
- package/dist/sdk/providers/opencode.d.ts.map +1 -1
- package/dist/sdk/providers/opencode.js +1 -82
- package/dist/sdk/providers/opencode.js.map +1 -1
- package/dist/sdk/types.d.ts +3 -1
- package/dist/sdk/types.d.ts.map +1 -1
- package/dist/services/ProjectQueueService.d.ts.map +1 -1
- package/dist/services/ProjectQueueService.js +3 -1
- package/dist/services/ProjectQueueService.js.map +1 -1
- package/dist/sessions/claude-summary.d.ts.map +1 -1
- package/dist/sessions/claude-summary.js +13 -1
- package/dist/sessions/claude-summary.js.map +1 -1
- package/dist/sessions/codex-reader.d.ts +0 -2
- package/dist/sessions/codex-reader.d.ts.map +1 -1
- package/dist/sessions/codex-reader.js +46 -84
- package/dist/sessions/codex-reader.js.map +1 -1
- package/dist/sessions/codex-user-turn-provenance.d.ts +40 -0
- package/dist/sessions/codex-user-turn-provenance.d.ts.map +1 -0
- package/dist/sessions/codex-user-turn-provenance.js +165 -0
- package/dist/sessions/codex-user-turn-provenance.js.map +1 -0
- package/dist/sessions/normalization.d.ts.map +1 -1
- package/dist/sessions/normalization.js +80 -51
- package/dist/sessions/normalization.js.map +1 -1
- package/dist/sessions/pagination.d.ts +6 -0
- package/dist/sessions/pagination.d.ts.map +1 -1
- package/dist/sessions/pagination.js +42 -2
- package/dist/sessions/pagination.js.map +1 -1
- package/dist/subscriptions.d.ts.map +1 -1
- package/dist/subscriptions.js +1 -0
- package/dist/subscriptions.js.map +1 -1
- package/dist/supervisor/Process.d.ts +12 -0
- package/dist/supervisor/Process.d.ts.map +1 -1
- package/dist/supervisor/Process.js +178 -22
- package/dist/supervisor/Process.js.map +1 -1
- package/dist/supervisor/Supervisor.d.ts +5 -1
- package/dist/supervisor/Supervisor.d.ts.map +1 -1
- package/dist/supervisor/Supervisor.js +47 -0
- package/dist/supervisor/Supervisor.js.map +1 -1
- package/package.json +2 -2
- package/client-dist/assets/de-CHMDbVD5.js +0 -6
- package/client-dist/assets/es-CK8MPF_C.js +0 -6
- package/client-dist/assets/fr-49PXQiUL.js +0 -6
- package/client-dist/assets/index-B-09fVut.js +0 -557
- package/client-dist/assets/index-uJnfvD1f.css +0 -1
- package/client-dist/assets/ja-CrCGPmoH.js +0 -6
- package/client-dist/assets/zh-CN-AFJxv5ke.js +0 -6
|
@@ -6,18 +6,20 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import { execFile, spawn } from "node:child_process";
|
|
8
8
|
import { homedir } from "node:os";
|
|
9
|
-
import {
|
|
10
|
-
import { HELPER_SIDE_MODEL_CHEAPEST, } from "../../../bundled/@yep-anywhere/shared/dist/index.js";
|
|
9
|
+
import { CODEX_TOOL_CORRELATION_FIELD, createCodexToolCorrelation, } from "../../../bundled/@yep-anywhere/shared/dist/index.js";
|
|
11
10
|
import { isCodexCorrelationDebugEnabled, logCodexCorrelationDebug, summarizeCodexNormalizedMessage, } from "../../codex/correlationDebugLogger.js";
|
|
12
|
-
import { canonicalizeCodexToolName, isCodexBackgroundProcessOutput, isCodexInterruptedToolOutput,
|
|
11
|
+
import { canonicalizeCodexToolName, isCodexBackgroundProcessOutput, isCodexInterruptedToolOutput, normalizeCodexCommandExecutionOutput, normalizeCodexCustomToolInvocation, normalizeCodexToolInvocation, normalizeCodexToolOutputWithContext, parseCodexToolArguments, } from "../../codex/normalization.js";
|
|
13
12
|
import { getLogger } from "../../logging/logger.js";
|
|
14
|
-
import { findCodexCliPath } from "../cli-detection.js";
|
|
13
|
+
import { findCodexCliPath, getCodexCliVersion } from "../cli-detection.js";
|
|
15
14
|
import { logSDKMessage } from "../messageLogger.js";
|
|
16
15
|
import { MessageQueue } from "../messageQueue.js";
|
|
17
16
|
import { createAgentctlSessionEnvBridge } from "./agentctl-session-env.js";
|
|
17
|
+
import { getFallbackCodexModelsForCliVersion, normalizeCodexModelList, normalizeSemver, } from "./codex-model-catalog.js";
|
|
18
|
+
import { asCodexAgentMessageDeltaNotification, asCodexCommandExecutionOutputDeltaNotification, asCodexErrorNotification, asCodexFileChangeOutputDeltaNotification, asCodexItemCompletedNotification, asCodexItemStartedNotification, asCodexPlanDeltaNotification, asCodexRawResponseItemCompletedNotification, asCodexReasoningSummaryTextDeltaNotification, asCodexThreadTokenUsageUpdatedNotification, asCodexTurnCompletedNotification, isCodexLiveDeltaNotificationMethod, isCodexLiveDeltaSuppressionEnabled, } from "./codex-notification-guards.js";
|
|
19
|
+
import { captureCodexSummaryTextFromNotification, captureCodexSummaryTextFromTurnItems, cleanCodexRecapText, cleanCodexSummaryText, CODEX_RECAP_TIMEOUT_MS, CODEX_SUMMARY_TIMEOUT_MS, createCodexForkSummaryPrompt, createCodexForkSummaryThreadResumeParams, createCodexRecapPrompt, joinCodexSummaryText, resolveCodexRecapHelperModel, } from "./codex-summary-helpers.js";
|
|
18
20
|
import { CODEX_BUILTIN_COMMANDS } from "./staticSlashCommands.js";
|
|
19
21
|
const log = getLogger().child({ component: "codex-provider" });
|
|
20
|
-
const
|
|
22
|
+
const CODEX_DESKTOP_BROWSER_SKILL_NAME = "browser:control-in-app-browser";
|
|
21
23
|
function logSdkCorrelationDebug(sessionId, message, metadata = {}) {
|
|
22
24
|
if (!isCodexCorrelationDebugEnabled())
|
|
23
25
|
return;
|
|
@@ -56,31 +58,8 @@ const MODEL_LIST_TIMEOUT_MS = 8000;
|
|
|
56
58
|
const APP_SERVER_INIT_REQUEST_ID = 1;
|
|
57
59
|
const APP_SERVER_MODEL_LIST_REQUEST_ID = 2;
|
|
58
60
|
const APP_SERVER_SHUTDOWN_GRACE_MS = 1500;
|
|
59
|
-
const CODEX_CLI_GPT55_MIN_VERSION = "0.124.0";
|
|
60
61
|
const CODEX_FAILURE_TRACE_LIMIT = 12;
|
|
61
62
|
const CODEX_FAILURE_PREVIEW_CHARS = 240;
|
|
62
|
-
const CODEX_RECAP_TIMEOUT_MS = 20_000;
|
|
63
|
-
const CODEX_SUMMARY_TIMEOUT_MS = 60_000;
|
|
64
|
-
const CODEX_RECAP_MAX_TOTAL_CHARS = 6000;
|
|
65
|
-
const CODEX_RECAP_CHEAPEST_MODEL_PREFERENCES = [
|
|
66
|
-
"gpt-5.4-mini",
|
|
67
|
-
"gpt-5.1-codex-mini",
|
|
68
|
-
"gpt-5.3-codex-spark",
|
|
69
|
-
];
|
|
70
|
-
const CODEX_DISABLE_LIVE_DELTAS_ENV = "YEP_CODEX_DISABLE_LIVE_DELTAS";
|
|
71
|
-
const CODEX_LIVE_DELTA_NOTIFICATION_METHODS = new Set([
|
|
72
|
-
"item/agentMessage/delta",
|
|
73
|
-
"item/plan/delta",
|
|
74
|
-
"item/reasoning/summaryTextDelta",
|
|
75
|
-
"item/commandExecution/outputDelta",
|
|
76
|
-
"item/fileChange/outputDelta",
|
|
77
|
-
]);
|
|
78
|
-
function isCodexLiveDeltaSuppressionEnabled() {
|
|
79
|
-
return process.env[CODEX_DISABLE_LIVE_DELTAS_ENV] === "true";
|
|
80
|
-
}
|
|
81
|
-
function isCodexLiveDeltaNotificationMethod(method) {
|
|
82
|
-
return CODEX_LIVE_DELTA_NOTIFICATION_METHODS.has(method);
|
|
83
|
-
}
|
|
84
63
|
const CODEX_THINKING_OFF_MIN_REASONING_EFFORT_PREFIXES = [
|
|
85
64
|
"gpt-5.3-codex-spark",
|
|
86
65
|
];
|
|
@@ -104,162 +83,6 @@ const CODEX_POLICY_OVERRIDES = {
|
|
|
104
83
|
const DECLARE_CODEX_ORIGINATOR = false;
|
|
105
84
|
const DECLARED_CODEX_ORIGINATOR = "Codex Desktop";
|
|
106
85
|
const YEP_ANYWHERE_ORIGINATOR = "yep-anywhere";
|
|
107
|
-
const PREFERRED_MODEL_ORDER = [
|
|
108
|
-
"gpt-5.5",
|
|
109
|
-
"gpt-5.4",
|
|
110
|
-
"gpt-5.4-mini",
|
|
111
|
-
"gpt-5.3-codex",
|
|
112
|
-
"gpt-5.3-codex-spark",
|
|
113
|
-
"gpt-5.2-codex",
|
|
114
|
-
"gpt-5.1-codex-max",
|
|
115
|
-
"gpt-5.2",
|
|
116
|
-
"gpt-5.1-codex-mini",
|
|
117
|
-
];
|
|
118
|
-
const FALLBACK_CODEX_MODELS = [
|
|
119
|
-
{
|
|
120
|
-
id: "gpt-5.5",
|
|
121
|
-
name: "GPT-5.5",
|
|
122
|
-
description: "Frontier model for complex coding, research, and real-world work.",
|
|
123
|
-
defaultReasoningEffort: "medium",
|
|
124
|
-
supportedReasoningEfforts: [
|
|
125
|
-
{
|
|
126
|
-
reasoningEffort: "low",
|
|
127
|
-
description: "Fast responses with lighter reasoning",
|
|
128
|
-
},
|
|
129
|
-
{
|
|
130
|
-
reasoningEffort: "medium",
|
|
131
|
-
description: "Balances speed and reasoning depth for everyday tasks",
|
|
132
|
-
},
|
|
133
|
-
{
|
|
134
|
-
reasoningEffort: "high",
|
|
135
|
-
description: "Greater reasoning depth for complex problems",
|
|
136
|
-
},
|
|
137
|
-
{
|
|
138
|
-
reasoningEffort: "xhigh",
|
|
139
|
-
description: "Extra high reasoning depth for complex problems",
|
|
140
|
-
},
|
|
141
|
-
],
|
|
142
|
-
inputModalities: ["text", "image"],
|
|
143
|
-
supportsPersonality: true,
|
|
144
|
-
serviceTiers: [
|
|
145
|
-
{
|
|
146
|
-
id: "priority",
|
|
147
|
-
name: "Fast",
|
|
148
|
-
description: "1.5x speed, increased usage",
|
|
149
|
-
},
|
|
150
|
-
],
|
|
151
|
-
},
|
|
152
|
-
{
|
|
153
|
-
id: "gpt-5.4",
|
|
154
|
-
name: "GPT-5.4",
|
|
155
|
-
description: "Strong model for everyday coding.",
|
|
156
|
-
isDefault: true,
|
|
157
|
-
defaultReasoningEffort: "medium",
|
|
158
|
-
supportedReasoningEfforts: [
|
|
159
|
-
{
|
|
160
|
-
reasoningEffort: "low",
|
|
161
|
-
description: "Fast responses with lighter reasoning",
|
|
162
|
-
},
|
|
163
|
-
{
|
|
164
|
-
reasoningEffort: "medium",
|
|
165
|
-
description: "Balances speed and reasoning depth for everyday tasks",
|
|
166
|
-
},
|
|
167
|
-
{
|
|
168
|
-
reasoningEffort: "high",
|
|
169
|
-
description: "Greater reasoning depth for complex problems",
|
|
170
|
-
},
|
|
171
|
-
{
|
|
172
|
-
reasoningEffort: "xhigh",
|
|
173
|
-
description: "Extra high reasoning depth for complex problems",
|
|
174
|
-
},
|
|
175
|
-
],
|
|
176
|
-
inputModalities: ["text", "image"],
|
|
177
|
-
supportsPersonality: true,
|
|
178
|
-
serviceTiers: [
|
|
179
|
-
{
|
|
180
|
-
id: "priority",
|
|
181
|
-
name: "Fast",
|
|
182
|
-
description: "1.5x speed, increased usage",
|
|
183
|
-
},
|
|
184
|
-
],
|
|
185
|
-
},
|
|
186
|
-
{
|
|
187
|
-
id: "gpt-5.4-mini",
|
|
188
|
-
name: "GPT-5.4-Mini",
|
|
189
|
-
description: "Small, fast, and cost-efficient model for simpler coding tasks.",
|
|
190
|
-
defaultReasoningEffort: "medium",
|
|
191
|
-
supportedReasoningEfforts: [
|
|
192
|
-
{
|
|
193
|
-
reasoningEffort: "low",
|
|
194
|
-
description: "Fast responses with lighter reasoning",
|
|
195
|
-
},
|
|
196
|
-
{
|
|
197
|
-
reasoningEffort: "medium",
|
|
198
|
-
description: "Balances speed and reasoning depth for everyday tasks",
|
|
199
|
-
},
|
|
200
|
-
{
|
|
201
|
-
reasoningEffort: "high",
|
|
202
|
-
description: "Greater reasoning depth for complex problems",
|
|
203
|
-
},
|
|
204
|
-
{
|
|
205
|
-
reasoningEffort: "xhigh",
|
|
206
|
-
description: "Extra high reasoning depth for complex problems",
|
|
207
|
-
},
|
|
208
|
-
],
|
|
209
|
-
inputModalities: ["text", "image"],
|
|
210
|
-
supportsPersonality: true,
|
|
211
|
-
},
|
|
212
|
-
{ id: "gpt-5.3-codex", name: "GPT-5.3-Codex" },
|
|
213
|
-
{ id: "gpt-5.3-codex-spark", name: "GPT-5.3-Codex-Spark" },
|
|
214
|
-
{ id: "gpt-5.2", name: "GPT-5.2" },
|
|
215
|
-
];
|
|
216
|
-
const LEGACY_FALLBACK_CODEX_MODELS = [
|
|
217
|
-
{ id: "gpt-5.3-codex", name: "GPT-5.3-Codex" },
|
|
218
|
-
{ id: "gpt-5.2-codex", name: "GPT-5.2-Codex" },
|
|
219
|
-
{ id: "gpt-5.1-codex-max", name: "GPT-5.1-Codex-Max" },
|
|
220
|
-
{ id: "gpt-5.2", name: "GPT-5.2" },
|
|
221
|
-
{ id: "gpt-5.1-codex-mini", name: "GPT-5.1-Codex-Mini" },
|
|
222
|
-
];
|
|
223
|
-
function normalizeSemver(raw) {
|
|
224
|
-
if (!raw)
|
|
225
|
-
return null;
|
|
226
|
-
const match = raw.match(/(\d+)\.(\d+)\.(\d+)(?:-([\w.]+))?/);
|
|
227
|
-
if (!match)
|
|
228
|
-
return null;
|
|
229
|
-
const [, major, minor, patch, pre] = match;
|
|
230
|
-
return pre
|
|
231
|
-
? `${major}.${minor}.${patch}-${pre}`
|
|
232
|
-
: `${major}.${minor}.${patch}`;
|
|
233
|
-
}
|
|
234
|
-
function compareSemver(a, b) {
|
|
235
|
-
const parsedA = splitSemver(a);
|
|
236
|
-
const parsedB = splitSemver(b);
|
|
237
|
-
for (let i = 0; i < 3; i++) {
|
|
238
|
-
const partA = parsedA.parts[i] ?? 0;
|
|
239
|
-
const partB = parsedB.parts[i] ?? 0;
|
|
240
|
-
if (partA !== partB)
|
|
241
|
-
return partA < partB ? -1 : 1;
|
|
242
|
-
}
|
|
243
|
-
if (parsedA.pre === null && parsedB.pre === null)
|
|
244
|
-
return 0;
|
|
245
|
-
if (parsedA.pre === null)
|
|
246
|
-
return 1;
|
|
247
|
-
if (parsedB.pre === null)
|
|
248
|
-
return -1;
|
|
249
|
-
return parsedA.pre < parsedB.pre ? -1 : parsedA.pre > parsedB.pre ? 1 : 0;
|
|
250
|
-
}
|
|
251
|
-
function splitSemver(version) {
|
|
252
|
-
const dashIndex = version.indexOf("-");
|
|
253
|
-
const core = dashIndex === -1 ? version : version.slice(0, dashIndex);
|
|
254
|
-
const pre = dashIndex === -1 ? null : version.slice(dashIndex + 1);
|
|
255
|
-
return {
|
|
256
|
-
parts: core.split(".").map((part) => {
|
|
257
|
-
const parsed = Number.parseInt(part, 10);
|
|
258
|
-
return Number.isFinite(parsed) ? parsed : 0;
|
|
259
|
-
}),
|
|
260
|
-
pre,
|
|
261
|
-
};
|
|
262
|
-
}
|
|
263
86
|
async function terminateChildProcess(child, graceMs = APP_SERVER_SHUTDOWN_GRACE_MS) {
|
|
264
87
|
if (!child?.pid || child.killed || child.exitCode !== null) {
|
|
265
88
|
return;
|
|
@@ -390,6 +213,9 @@ class CodexAppServerClient {
|
|
|
390
213
|
this.env = env;
|
|
391
214
|
this.shouldSuppressNotification = shouldSuppressNotification;
|
|
392
215
|
}
|
|
216
|
+
get isClosed() {
|
|
217
|
+
return this.closed;
|
|
218
|
+
}
|
|
393
219
|
setServerRequestHandler(handler) {
|
|
394
220
|
this.onServerRequest = handler;
|
|
395
221
|
}
|
|
@@ -598,6 +424,7 @@ class CodexAppServerClient {
|
|
|
598
424
|
params: {
|
|
599
425
|
error: { message: error.message },
|
|
600
426
|
willRetry: false,
|
|
427
|
+
codexProcessExit: true,
|
|
601
428
|
},
|
|
602
429
|
});
|
|
603
430
|
this.notifications.close(error);
|
|
@@ -724,7 +551,7 @@ export class CodexProvider {
|
|
|
724
551
|
async getModelsFromAppServer() {
|
|
725
552
|
try {
|
|
726
553
|
const appServerModels = await this.requestAppServerModelList();
|
|
727
|
-
return
|
|
554
|
+
return normalizeCodexModelList(appServerModels);
|
|
728
555
|
}
|
|
729
556
|
catch (error) {
|
|
730
557
|
log.debug({ error }, "Failed to query Codex app-server model list, using fallback models");
|
|
@@ -839,153 +666,20 @@ export class CodexProvider {
|
|
|
839
666
|
})}\n`);
|
|
840
667
|
});
|
|
841
668
|
}
|
|
842
|
-
normalizeModelList(models) {
|
|
843
|
-
const orderLookup = new Map(PREFERRED_MODEL_ORDER.map((id, idx) => [id, idx]));
|
|
844
|
-
const deduped = new Map();
|
|
845
|
-
for (const [serverIndex, model] of models.entries()) {
|
|
846
|
-
if (model.hidden === true)
|
|
847
|
-
continue;
|
|
848
|
-
const modelId = (model.model || model.id || "").trim();
|
|
849
|
-
if (!modelId)
|
|
850
|
-
continue;
|
|
851
|
-
deduped.set(modelId, {
|
|
852
|
-
model: {
|
|
853
|
-
id: modelId,
|
|
854
|
-
name: this.formatModelName(model.displayName || modelId),
|
|
855
|
-
description: model.description,
|
|
856
|
-
...(model.isDefault === true ? { isDefault: true } : {}),
|
|
857
|
-
...this.normalizeModelReasoningMetadata(model),
|
|
858
|
-
...(Array.isArray(model.inputModalities)
|
|
859
|
-
? { inputModalities: model.inputModalities }
|
|
860
|
-
: {}),
|
|
861
|
-
...(typeof model.supportsPersonality === "boolean"
|
|
862
|
-
? { supportsPersonality: model.supportsPersonality }
|
|
863
|
-
: {}),
|
|
864
|
-
...this.normalizeModelServiceTierMetadata(model),
|
|
865
|
-
},
|
|
866
|
-
serverIndex,
|
|
867
|
-
});
|
|
868
|
-
const upgradeId = model.upgrade?.trim() ||
|
|
869
|
-
(typeof model.upgradeInfo?.model === "string"
|
|
870
|
-
? model.upgradeInfo.model.trim()
|
|
871
|
-
: "");
|
|
872
|
-
if (upgradeId && !deduped.has(upgradeId)) {
|
|
873
|
-
deduped.set(upgradeId, {
|
|
874
|
-
model: {
|
|
875
|
-
id: upgradeId,
|
|
876
|
-
name: this.formatModelName(upgradeId),
|
|
877
|
-
},
|
|
878
|
-
serverIndex,
|
|
879
|
-
});
|
|
880
|
-
}
|
|
881
|
-
}
|
|
882
|
-
return [...deduped.values()]
|
|
883
|
-
.map((entry, index) => ({
|
|
884
|
-
model: entry.model,
|
|
885
|
-
index,
|
|
886
|
-
rank: this.getModelSortRank(entry.model, entry.serverIndex, orderLookup),
|
|
887
|
-
}))
|
|
888
|
-
.sort((a, b) => a.rank - b.rank || a.index - b.index)
|
|
889
|
-
.map((entry) => entry.model);
|
|
890
|
-
}
|
|
891
|
-
normalizeModelReasoningMetadata(model) {
|
|
892
|
-
const metadata = {};
|
|
893
|
-
if (typeof model.defaultReasoningEffort === "string") {
|
|
894
|
-
metadata.defaultReasoningEffort = model.defaultReasoningEffort;
|
|
895
|
-
}
|
|
896
|
-
if (Array.isArray(model.supportedReasoningEfforts)) {
|
|
897
|
-
const efforts = model.supportedReasoningEfforts
|
|
898
|
-
.map((effort) => {
|
|
899
|
-
if (typeof effort.reasoningEffort !== "string")
|
|
900
|
-
return null;
|
|
901
|
-
return {
|
|
902
|
-
reasoningEffort: effort.reasoningEffort,
|
|
903
|
-
...(typeof effort.description === "string"
|
|
904
|
-
? { description: effort.description }
|
|
905
|
-
: {}),
|
|
906
|
-
};
|
|
907
|
-
})
|
|
908
|
-
.filter((effort) => effort !== null);
|
|
909
|
-
if (efforts.length > 0) {
|
|
910
|
-
metadata.supportedReasoningEfforts = efforts;
|
|
911
|
-
}
|
|
912
|
-
}
|
|
913
|
-
return metadata;
|
|
914
|
-
}
|
|
915
|
-
normalizeModelServiceTierMetadata(model) {
|
|
916
|
-
if (!Array.isArray(model.serviceTiers)) {
|
|
917
|
-
return {};
|
|
918
|
-
}
|
|
919
|
-
const serviceTiers = model.serviceTiers
|
|
920
|
-
.map((tier) => {
|
|
921
|
-
const id = typeof tier.id === "string" ? tier.id.trim() : "";
|
|
922
|
-
const name = typeof tier.name === "string" ? tier.name.trim() : "";
|
|
923
|
-
if (!id || !name)
|
|
924
|
-
return null;
|
|
925
|
-
return {
|
|
926
|
-
id,
|
|
927
|
-
name,
|
|
928
|
-
...(typeof tier.description === "string"
|
|
929
|
-
? { description: tier.description }
|
|
930
|
-
: {}),
|
|
931
|
-
};
|
|
932
|
-
})
|
|
933
|
-
.filter((tier) => tier !== null);
|
|
934
|
-
return serviceTiers.length > 0 ? { serviceTiers } : {};
|
|
935
|
-
}
|
|
936
|
-
getModelSortRank(model, serverIndex, orderLookup) {
|
|
937
|
-
if (model.id === "gpt-5.5") {
|
|
938
|
-
return 0;
|
|
939
|
-
}
|
|
940
|
-
if (model.isDefault) {
|
|
941
|
-
return 1;
|
|
942
|
-
}
|
|
943
|
-
const preferredRank = orderLookup.get(model.id);
|
|
944
|
-
if (preferredRank !== undefined) {
|
|
945
|
-
return 2 + preferredRank;
|
|
946
|
-
}
|
|
947
|
-
return 2 + PREFERRED_MODEL_ORDER.length + serverIndex;
|
|
948
|
-
}
|
|
949
669
|
async getFallbackCodexModels() {
|
|
950
670
|
const version = await this.getInstalledCodexCliVersion();
|
|
951
|
-
|
|
952
|
-
return LEGACY_FALLBACK_CODEX_MODELS;
|
|
953
|
-
}
|
|
954
|
-
return FALLBACK_CODEX_MODELS;
|
|
671
|
+
return getFallbackCodexModelsForCliVersion(version);
|
|
955
672
|
}
|
|
956
673
|
async getInstalledCodexCliVersion() {
|
|
957
674
|
try {
|
|
958
675
|
const codexCommand = await this.resolveCodexCommand();
|
|
959
|
-
const
|
|
960
|
-
|
|
961
|
-
timeout: 3000,
|
|
962
|
-
});
|
|
963
|
-
return normalizeSemver(stdout);
|
|
676
|
+
const version = await getCodexCliVersion(codexCommand);
|
|
677
|
+
return normalizeSemver(version);
|
|
964
678
|
}
|
|
965
679
|
catch {
|
|
966
680
|
return null;
|
|
967
681
|
}
|
|
968
682
|
}
|
|
969
|
-
formatModelName(value) {
|
|
970
|
-
return value
|
|
971
|
-
.trim()
|
|
972
|
-
.split("-")
|
|
973
|
-
.map((part) => {
|
|
974
|
-
const lower = part.toLowerCase();
|
|
975
|
-
if (lower === "gpt")
|
|
976
|
-
return "GPT";
|
|
977
|
-
if (lower === "codex")
|
|
978
|
-
return "Codex";
|
|
979
|
-
if (lower === "mini")
|
|
980
|
-
return "Mini";
|
|
981
|
-
if (lower === "max")
|
|
982
|
-
return "Max";
|
|
983
|
-
if (lower.length === 0)
|
|
984
|
-
return "";
|
|
985
|
-
return lower.charAt(0).toUpperCase() + lower.slice(1);
|
|
986
|
-
})
|
|
987
|
-
.join("-");
|
|
988
|
-
}
|
|
989
683
|
mapEffortToReasoningEffort(effort, thinking, model) {
|
|
990
684
|
if (thinking?.type === "disabled") {
|
|
991
685
|
const normalizedModel = model?.trim().toLowerCase();
|
|
@@ -1436,10 +1130,13 @@ export class CodexProvider {
|
|
|
1436
1130
|
turnResult.turn.error?.message) {
|
|
1437
1131
|
yield {
|
|
1438
1132
|
type: "error",
|
|
1133
|
+
uuid: `codex-error-${turnResult.turn.id}`,
|
|
1439
1134
|
session_id: sessionId,
|
|
1440
1135
|
error: turnResult.turn.error.message,
|
|
1441
1136
|
codexErrorInfo: turnResult.turn.error.codexErrorInfo ?? null,
|
|
1442
1137
|
codexAdditionalDetails: turnResult.turn.error.additionalDetails ?? null,
|
|
1138
|
+
codexWillRetry: false,
|
|
1139
|
+
codexTurnId: turnResult.turn.id,
|
|
1443
1140
|
codexFailureTrace: this.snapshotCodexFailureTrace(failureTrace),
|
|
1444
1141
|
codexFailureSummary: this.formatCodexFailureTrace(failureTrace),
|
|
1445
1142
|
codexRequestId: this.extractOpenAIRequestId(turnResult.turn.error, turnResult.turn.error.additionalDetails, turnResult.turn.error.message),
|
|
@@ -1455,8 +1152,16 @@ export class CodexProvider {
|
|
|
1455
1152
|
const codexFailureTrace = this.snapshotCodexFailureTrace(failureTrace);
|
|
1456
1153
|
log.error({ error, codexFailureTrace }, "Error in codex app-server session");
|
|
1457
1154
|
if (!signal.aborted) {
|
|
1155
|
+
const isProcessFailure = appServer.isClosed;
|
|
1458
1156
|
yield {
|
|
1459
1157
|
type: "error",
|
|
1158
|
+
...(isProcessFailure
|
|
1159
|
+
? {
|
|
1160
|
+
uuid: `codex-error-${sessionId || "unknown"}-process-exit`,
|
|
1161
|
+
codexWillRetry: false,
|
|
1162
|
+
codexErrorScope: "app_server_process",
|
|
1163
|
+
}
|
|
1164
|
+
: {}),
|
|
1460
1165
|
session_id: sessionId,
|
|
1461
1166
|
error: error instanceof Error ? error.message : String(error),
|
|
1462
1167
|
codexFailureTrace,
|
|
@@ -1491,18 +1196,24 @@ export class CodexProvider {
|
|
|
1491
1196
|
}
|
|
1492
1197
|
isTurnTerminalNotification(notification, turnId) {
|
|
1493
1198
|
if (notification.method === "turn/completed") {
|
|
1494
|
-
const params =
|
|
1199
|
+
const params = asCodexTurnCompletedNotification(notification.params);
|
|
1495
1200
|
return params?.turn.id === turnId;
|
|
1496
1201
|
}
|
|
1497
1202
|
if (notification.method === "error") {
|
|
1498
|
-
const params =
|
|
1499
|
-
|
|
1203
|
+
const params = asCodexErrorNotification(notification.params);
|
|
1204
|
+
if (params) {
|
|
1205
|
+
return params.turnId === turnId && !params.willRetry;
|
|
1206
|
+
}
|
|
1207
|
+
const rawParams = notification.params && typeof notification.params === "object"
|
|
1208
|
+
? notification.params
|
|
1209
|
+
: null;
|
|
1210
|
+
return (rawParams?.codexProcessExit === true && rawParams.willRetry === false);
|
|
1500
1211
|
}
|
|
1501
1212
|
return false;
|
|
1502
1213
|
}
|
|
1503
1214
|
updateBackgroundProcessTracking(notification, runtimeState) {
|
|
1504
1215
|
if (notification.method === "rawResponseItem/completed") {
|
|
1505
|
-
const params =
|
|
1216
|
+
const params = asCodexRawResponseItemCompletedNotification(notification.params);
|
|
1506
1217
|
const item = params?.item && typeof params.item === "object"
|
|
1507
1218
|
? params.item
|
|
1508
1219
|
: null;
|
|
@@ -1530,7 +1241,7 @@ export class CodexProvider {
|
|
|
1530
1241
|
return;
|
|
1531
1242
|
}
|
|
1532
1243
|
if (notification.method === "item/completed") {
|
|
1533
|
-
const params =
|
|
1244
|
+
const params = asCodexItemCompletedNotification(notification.params);
|
|
1534
1245
|
if (!params)
|
|
1535
1246
|
return;
|
|
1536
1247
|
const normalized = this.normalizeThreadItem(params.item);
|
|
@@ -1541,7 +1252,7 @@ export class CodexProvider {
|
|
|
1541
1252
|
return;
|
|
1542
1253
|
}
|
|
1543
1254
|
if (notification.method === "item/started") {
|
|
1544
|
-
const params =
|
|
1255
|
+
const params = asCodexItemStartedNotification(notification.params);
|
|
1545
1256
|
if (!params)
|
|
1546
1257
|
return;
|
|
1547
1258
|
const normalized = this.normalizeThreadItem(params.item);
|
|
@@ -1605,7 +1316,7 @@ export class CodexProvider {
|
|
|
1605
1316
|
threadId: options.sessionId,
|
|
1606
1317
|
cwd: options.cwd,
|
|
1607
1318
|
...this.buildThreadPermissionParams(policy),
|
|
1608
|
-
config:
|
|
1319
|
+
config: this.buildThreadConfigOverrides({}),
|
|
1609
1320
|
};
|
|
1610
1321
|
if (experimentalApiEnabled) {
|
|
1611
1322
|
params.excludeTurns = true;
|
|
@@ -1673,11 +1384,25 @@ export class CodexProvider {
|
|
|
1673
1384
|
};
|
|
1674
1385
|
}
|
|
1675
1386
|
buildThreadConfigOverrides(options) {
|
|
1387
|
+
// The OpenAI browser plugin controls a desktop-owned browser backend that
|
|
1388
|
+
// YA's Codex app-server host does not provide. Suppress the unavailable
|
|
1389
|
+
// skill at thread scope so Codex follows YA's Playwright fallback instead
|
|
1390
|
+
// of advertising a browser that fails during backend discovery.
|
|
1391
|
+
const config = {
|
|
1392
|
+
skills: {
|
|
1393
|
+
config: [
|
|
1394
|
+
{
|
|
1395
|
+
name: CODEX_DESKTOP_BROWSER_SKILL_NAME,
|
|
1396
|
+
enabled: false,
|
|
1397
|
+
},
|
|
1398
|
+
],
|
|
1399
|
+
},
|
|
1400
|
+
};
|
|
1676
1401
|
const reasoningEffort = this.mapEffortToReasoningEffort(options.effort, options.thinking, options.model);
|
|
1677
|
-
if (
|
|
1678
|
-
|
|
1402
|
+
if (reasoningEffort) {
|
|
1403
|
+
config.model_reasoning_effort = reasoningEffort;
|
|
1679
1404
|
}
|
|
1680
|
-
return
|
|
1405
|
+
return config;
|
|
1681
1406
|
}
|
|
1682
1407
|
createTurnStartParams(threadId, userPrompt, options, turnPolicy = null) {
|
|
1683
1408
|
return {
|
|
@@ -1712,8 +1437,8 @@ export class CodexProvider {
|
|
|
1712
1437
|
}
|
|
1713
1438
|
}
|
|
1714
1439
|
async generateSideSessionRecap(recentAssistantText, requestedModel) {
|
|
1715
|
-
const userPrompt =
|
|
1716
|
-
const model = await this.
|
|
1440
|
+
const userPrompt = createCodexRecapPrompt(recentAssistantText);
|
|
1441
|
+
const model = await resolveCodexRecapHelperModel(requestedModel, () => this.getAvailableModels());
|
|
1717
1442
|
const codexCommand = await this.resolveCodexCommand();
|
|
1718
1443
|
const abortController = new AbortController();
|
|
1719
1444
|
let timedOut = false;
|
|
@@ -1745,18 +1470,19 @@ export class CodexProvider {
|
|
|
1745
1470
|
summary: "auto",
|
|
1746
1471
|
});
|
|
1747
1472
|
const textByItemId = new Map();
|
|
1748
|
-
this.
|
|
1473
|
+
const normalizeThreadItem = this.normalizeThreadItem.bind(this);
|
|
1474
|
+
captureCodexSummaryTextFromTurnItems(turnResult.turn.items, textByItemId, normalizeThreadItem);
|
|
1749
1475
|
if (turnResult.turn.status === "failed") {
|
|
1750
1476
|
throw new Error(turnResult.turn.error?.message ?? "Codex recap generation failed");
|
|
1751
1477
|
}
|
|
1752
1478
|
let turnComplete = turnResult.turn.status !== "inProgress";
|
|
1753
1479
|
while (!turnComplete && !abortController.signal.aborted) {
|
|
1754
1480
|
const notification = await appServer.nextNotification(abortController.signal);
|
|
1755
|
-
|
|
1481
|
+
captureCodexSummaryTextFromNotification(notification, textByItemId, normalizeThreadItem);
|
|
1756
1482
|
if (notification.method !== "turn/completed") {
|
|
1757
1483
|
continue;
|
|
1758
1484
|
}
|
|
1759
|
-
const completed =
|
|
1485
|
+
const completed = asCodexTurnCompletedNotification(notification.params);
|
|
1760
1486
|
if (completed?.turn.status === "failed") {
|
|
1761
1487
|
throw new Error(completed.turn.error?.message ?? "Codex recap generation failed");
|
|
1762
1488
|
}
|
|
@@ -1765,10 +1491,7 @@ export class CodexProvider {
|
|
|
1765
1491
|
if (abortController.signal.aborted) {
|
|
1766
1492
|
throw new Error("Timed out generating Codex recap");
|
|
1767
1493
|
}
|
|
1768
|
-
const cleaned =
|
|
1769
|
-
.join("\n")
|
|
1770
|
-
.replace(/\s*\(disable recaps in \/config\)\s*$/u, "")
|
|
1771
|
-
.trim();
|
|
1494
|
+
const cleaned = cleanCodexRecapText(joinCodexSummaryText(textByItemId));
|
|
1772
1495
|
if (!cleaned) {
|
|
1773
1496
|
throw new Error("Recap generation returned empty text");
|
|
1774
1497
|
}
|
|
@@ -1786,46 +1509,8 @@ export class CodexProvider {
|
|
|
1786
1509
|
await appServer.close();
|
|
1787
1510
|
}
|
|
1788
1511
|
}
|
|
1789
|
-
createRecapPrompt(recentAssistantText) {
|
|
1790
|
-
const trimmed = recentAssistantText
|
|
1791
|
-
.map((text) => text.trim())
|
|
1792
|
-
.filter((text) => text.length > 0);
|
|
1793
|
-
if (trimmed.length === 0) {
|
|
1794
|
-
throw new Error("No recent assistant text to summarize");
|
|
1795
|
-
}
|
|
1796
|
-
let total = 0;
|
|
1797
|
-
const tail = [];
|
|
1798
|
-
for (let i = trimmed.length - 1; i >= 0; i--) {
|
|
1799
|
-
const entry = trimmed[i] ?? "";
|
|
1800
|
-
if (total + entry.length > CODEX_RECAP_MAX_TOTAL_CHARS) {
|
|
1801
|
-
break;
|
|
1802
|
-
}
|
|
1803
|
-
tail.unshift(entry);
|
|
1804
|
-
total += entry.length;
|
|
1805
|
-
}
|
|
1806
|
-
if (tail.length === 0) {
|
|
1807
|
-
const last = trimmed[trimmed.length - 1] ?? "";
|
|
1808
|
-
tail.push(last.slice(-CODEX_RECAP_MAX_TOTAL_CHARS));
|
|
1809
|
-
}
|
|
1810
|
-
const transcript = tail
|
|
1811
|
-
.map((text, index) => `--- Assistant turn ${index + 1} ---\n${text}`)
|
|
1812
|
-
.join("\n\n");
|
|
1813
|
-
return [
|
|
1814
|
-
"The user stepped away and is coming back. Recap in under 40 words,",
|
|
1815
|
-
"1-2 plain sentences, no markdown. Lead with the overall thrust of what",
|
|
1816
|
-
"the assistant did or is doing; mention any pending next action.",
|
|
1817
|
-
"Do not greet, do not ask a question, do not add a sign-off.",
|
|
1818
|
-
"",
|
|
1819
|
-
"Recent assistant output:",
|
|
1820
|
-
transcript,
|
|
1821
|
-
].join("\n");
|
|
1822
|
-
}
|
|
1823
1512
|
async generateForkBackedSummary(request) {
|
|
1824
|
-
const userPrompt = request
|
|
1825
|
-
? this.createSessionRetitlePrompt(request)
|
|
1826
|
-
: request.purpose === "recap"
|
|
1827
|
-
? this.createForkedRecapPrompt()
|
|
1828
|
-
: this.createForkAfterSummaryPrompt(request);
|
|
1513
|
+
const userPrompt = createCodexForkSummaryPrompt(request);
|
|
1829
1514
|
const codexCommand = await this.resolveCodexCommand();
|
|
1830
1515
|
const appServer = new CodexAppServerClient(codexCommand, request.cwd, this.getCodexEnv());
|
|
1831
1516
|
const abortController = new AbortController();
|
|
@@ -1856,7 +1541,7 @@ export class CodexProvider {
|
|
|
1856
1541
|
await appServer.connect();
|
|
1857
1542
|
const experimentalApiEnabled = await this.initializeAppServer(appServer);
|
|
1858
1543
|
appServer.notify("initialized");
|
|
1859
|
-
const threadResult = await appServer.request("thread/resume",
|
|
1544
|
+
const threadResult = await appServer.request("thread/resume", createCodexForkSummaryThreadResumeParams(request, experimentalApiEnabled));
|
|
1860
1545
|
const threadId = threadResult.thread.id || request.generatorSessionId;
|
|
1861
1546
|
const turnResult = await appServer.request("turn/start", {
|
|
1862
1547
|
threadId,
|
|
@@ -1866,7 +1551,8 @@ export class CodexProvider {
|
|
|
1866
1551
|
approvalPolicy: "untrusted",
|
|
1867
1552
|
});
|
|
1868
1553
|
const textByItemId = new Map();
|
|
1869
|
-
this.
|
|
1554
|
+
const normalizeThreadItem = this.normalizeThreadItem.bind(this);
|
|
1555
|
+
captureCodexSummaryTextFromTurnItems(turnResult.turn.items, textByItemId, normalizeThreadItem);
|
|
1870
1556
|
if (turnResult.turn.status === "failed") {
|
|
1871
1557
|
throw new Error(turnResult.turn.error?.message ?? "Codex summary generation failed");
|
|
1872
1558
|
}
|
|
@@ -1874,13 +1560,13 @@ export class CodexProvider {
|
|
|
1874
1560
|
let turnComplete = turnResult.turn.status !== "inProgress";
|
|
1875
1561
|
while (!turnComplete && !abortController.signal.aborted) {
|
|
1876
1562
|
const notification = await appServer.nextNotification(abortController.signal);
|
|
1877
|
-
|
|
1563
|
+
captureCodexSummaryTextFromNotification(notification, textByItemId, normalizeThreadItem);
|
|
1878
1564
|
if (notification.method === "turn/completed") {
|
|
1879
|
-
const completed =
|
|
1565
|
+
const completed = asCodexTurnCompletedNotification(notification.params);
|
|
1880
1566
|
if (completed?.turn.id !== turnId) {
|
|
1881
1567
|
continue;
|
|
1882
1568
|
}
|
|
1883
|
-
|
|
1569
|
+
captureCodexSummaryTextFromTurnItems(completed.turn.items, textByItemId, normalizeThreadItem);
|
|
1884
1570
|
if (completed.turn.status === "failed") {
|
|
1885
1571
|
throw new Error(completed.turn.error?.message ??
|
|
1886
1572
|
"Codex summary generation failed");
|
|
@@ -1889,7 +1575,7 @@ export class CodexProvider {
|
|
|
1889
1575
|
continue;
|
|
1890
1576
|
}
|
|
1891
1577
|
if (notification.method === "error") {
|
|
1892
|
-
const error =
|
|
1578
|
+
const error = asCodexErrorNotification(notification.params);
|
|
1893
1579
|
if (error?.turnId === turnId && !error.willRetry) {
|
|
1894
1580
|
throw new Error(error.error.message ?? "Codex summary generation failed");
|
|
1895
1581
|
}
|
|
@@ -1901,7 +1587,7 @@ export class CodexProvider {
|
|
|
1901
1587
|
}
|
|
1902
1588
|
throw new Error("Timed out generating Codex summary");
|
|
1903
1589
|
}
|
|
1904
|
-
const cleaned =
|
|
1590
|
+
const cleaned = cleanCodexSummaryText(joinCodexSummaryText(textByItemId));
|
|
1905
1591
|
if (!cleaned) {
|
|
1906
1592
|
throw new Error("Summary generation returned empty text");
|
|
1907
1593
|
}
|
|
@@ -1923,84 +1609,6 @@ export class CodexProvider {
|
|
|
1923
1609
|
await appServer.close();
|
|
1924
1610
|
}
|
|
1925
1611
|
}
|
|
1926
|
-
createForkSummaryThreadResumeParams(request, experimentalApiEnabled = false) {
|
|
1927
|
-
const params = {
|
|
1928
|
-
threadId: request.generatorSessionId,
|
|
1929
|
-
model: null,
|
|
1930
|
-
cwd: request.cwd,
|
|
1931
|
-
approvalPolicy: "untrusted",
|
|
1932
|
-
sandbox: "read-only",
|
|
1933
|
-
config: null,
|
|
1934
|
-
developerInstructions: request.purpose === "session-retitle"
|
|
1935
|
-
? "You are a title helper. Reply with the session title only, no preamble. Do not call tools."
|
|
1936
|
-
: request.purpose === "recap"
|
|
1937
|
-
? "You are a recap helper. Reply with the recap text only, no preamble. Do not call tools."
|
|
1938
|
-
: "You are a handoff summary helper. Reply with the summary text only, no preamble. Do not call tools.",
|
|
1939
|
-
};
|
|
1940
|
-
if (experimentalApiEnabled) {
|
|
1941
|
-
params.excludeTurns = true;
|
|
1942
|
-
}
|
|
1943
|
-
return params;
|
|
1944
|
-
}
|
|
1945
|
-
createForkAfterSummaryPrompt(request) {
|
|
1946
|
-
const instructions = request.instructions?.trim();
|
|
1947
|
-
const boundaryContext = request.afterTurnContext?.trim();
|
|
1948
|
-
return [
|
|
1949
|
-
"The first non-empty line must be a concise title of at most 120 characters, with no trailing period.",
|
|
1950
|
-
"Write it as: Title: <title>",
|
|
1951
|
-
"Then leave one blank line before the handoff summary.",
|
|
1952
|
-
"",
|
|
1953
|
-
"Summarize the useful state after the retained fork boundary for a peer-agent handoff.",
|
|
1954
|
-
`The target fork retains the conversation through completed-turn message id ${request.afterTurnMessageId}.`,
|
|
1955
|
-
boundaryContext
|
|
1956
|
-
? `The retained boundary is the completed turn ending with this excerpt:\n${boundaryContext}`
|
|
1957
|
-
: undefined,
|
|
1958
|
-
"The target fork already includes the original request and the assistant/tool work through that selected completed turn.",
|
|
1959
|
-
"Do not repeat setup, instruction loading, initial repository orientation, or investigation already present in that retained prefix.",
|
|
1960
|
-
"Preserve decisions, constraints, current state, changed files, verification evidence, open risks, and the next useful action.",
|
|
1961
|
-
"Do not continue the task. Write text that can be submitted as the next user turn in the target fork.",
|
|
1962
|
-
instructions ? "" : undefined,
|
|
1963
|
-
instructions ? "Additional user instructions:" : undefined,
|
|
1964
|
-
instructions || undefined,
|
|
1965
|
-
]
|
|
1966
|
-
.filter((part) => part !== undefined)
|
|
1967
|
-
.join("\n");
|
|
1968
|
-
}
|
|
1969
|
-
createForkedRecapPrompt() {
|
|
1970
|
-
return [
|
|
1971
|
-
"The user stepped away and is coming back.",
|
|
1972
|
-
"Recap the current session state in under 40 words, 1-2 plain sentences, no markdown.",
|
|
1973
|
-
"Lead with what the assistant did or is doing; mention any pending next action.",
|
|
1974
|
-
"Do not greet, do not ask a question, do not add a sign-off.",
|
|
1975
|
-
].join("\n");
|
|
1976
|
-
}
|
|
1977
|
-
createSessionRetitlePrompt(request) {
|
|
1978
|
-
const lengthTarget = request.lengthTarget ?? 80;
|
|
1979
|
-
const currentTitle = request.currentTitle?.trim();
|
|
1980
|
-
return [
|
|
1981
|
-
"What is a good new title for this session?",
|
|
1982
|
-
"",
|
|
1983
|
-
`Target length: under ${lengthTarget} characters.`,
|
|
1984
|
-
currentTitle ? `Current title: ${currentTitle}` : undefined,
|
|
1985
|
-
"Prefer a concrete task/result phrase over a generic chat title.",
|
|
1986
|
-
"Return only the title. Do not quote it. Do not add a trailing period.",
|
|
1987
|
-
]
|
|
1988
|
-
.filter((part) => part !== undefined)
|
|
1989
|
-
.join("\n");
|
|
1990
|
-
}
|
|
1991
|
-
async resolveRecapHelperModel(requestedModel) {
|
|
1992
|
-
if (!requestedModel || requestedModel !== HELPER_SIDE_MODEL_CHEAPEST) {
|
|
1993
|
-
return requestedModel ?? null;
|
|
1994
|
-
}
|
|
1995
|
-
const models = await this.getAvailableModels();
|
|
1996
|
-
for (const preferred of CODEX_RECAP_CHEAPEST_MODEL_PREFERENCES) {
|
|
1997
|
-
if (models.some((model) => model.id === preferred)) {
|
|
1998
|
-
return preferred;
|
|
1999
|
-
}
|
|
2000
|
-
}
|
|
2001
|
-
return (models.find((model) => model.id.toLowerCase().includes("mini"))?.id ??
|
|
2002
|
-
null);
|
|
2003
|
-
}
|
|
2004
1612
|
handleRecapServerRequest(request) {
|
|
2005
1613
|
return this.handleNonTurnServerRequest(request, "recap helper");
|
|
2006
1614
|
}
|
|
@@ -2029,63 +1637,6 @@ export class CodexProvider {
|
|
|
2029
1637
|
return Promise.resolve({});
|
|
2030
1638
|
}
|
|
2031
1639
|
}
|
|
2032
|
-
captureRecapTextFromTurnItems(items, textByItemId) {
|
|
2033
|
-
for (const item of items) {
|
|
2034
|
-
const normalized = this.normalizeThreadItem(item);
|
|
2035
|
-
if (normalized?.type === "agent_message" && normalized.text.trim()) {
|
|
2036
|
-
textByItemId.set(normalized.id, normalized.text);
|
|
2037
|
-
}
|
|
2038
|
-
}
|
|
2039
|
-
}
|
|
2040
|
-
captureRecapTextFromNotification(notification, textByItemId) {
|
|
2041
|
-
if (notification.method === "item/agentMessage/delta") {
|
|
2042
|
-
const params = this.asAgentMessageDeltaNotification(notification.params);
|
|
2043
|
-
if (!params?.delta)
|
|
2044
|
-
return;
|
|
2045
|
-
textByItemId.set(params.itemId, `${textByItemId.get(params.itemId) ?? ""}${params.delta}`);
|
|
2046
|
-
return;
|
|
2047
|
-
}
|
|
2048
|
-
if (notification.method === "item/completed") {
|
|
2049
|
-
const params = this.asItemCompletedNotification(notification.params);
|
|
2050
|
-
if (!params || textByItemId.has(params.item.id))
|
|
2051
|
-
return;
|
|
2052
|
-
const normalized = this.normalizeThreadItem(params.item);
|
|
2053
|
-
if (normalized?.type === "agent_message" && normalized.text.trim()) {
|
|
2054
|
-
textByItemId.set(normalized.id, normalized.text);
|
|
2055
|
-
}
|
|
2056
|
-
return;
|
|
2057
|
-
}
|
|
2058
|
-
if (notification.method !== "rawResponseItem/completed") {
|
|
2059
|
-
return;
|
|
2060
|
-
}
|
|
2061
|
-
const params = this.asRawResponseItemCompletedNotification(notification.params);
|
|
2062
|
-
const text = this.extractRawResponseMessageText(params?.item);
|
|
2063
|
-
if (params && text) {
|
|
2064
|
-
textByItemId.set(`raw-${params.turnId}-${textByItemId.size}`, text);
|
|
2065
|
-
}
|
|
2066
|
-
}
|
|
2067
|
-
extractRawResponseMessageText(item) {
|
|
2068
|
-
if (!item || typeof item !== "object")
|
|
2069
|
-
return null;
|
|
2070
|
-
const record = item;
|
|
2071
|
-
if (record.type !== "message" || record.role !== "assistant") {
|
|
2072
|
-
return null;
|
|
2073
|
-
}
|
|
2074
|
-
if (!Array.isArray(record.content)) {
|
|
2075
|
-
return null;
|
|
2076
|
-
}
|
|
2077
|
-
const parts = record.content
|
|
2078
|
-
.map((contentItem) => {
|
|
2079
|
-
if (!contentItem || typeof contentItem !== "object")
|
|
2080
|
-
return "";
|
|
2081
|
-
const contentRecord = contentItem;
|
|
2082
|
-
return contentRecord.type === "output_text"
|
|
2083
|
-
? (this.getOptionalString(contentRecord.text) ?? "")
|
|
2084
|
-
: "";
|
|
2085
|
-
})
|
|
2086
|
-
.filter((text) => text.length > 0);
|
|
2087
|
-
return parts.length > 0 ? parts.join("\n") : null;
|
|
2088
|
-
}
|
|
2089
1640
|
createSessionConfigAckMessage(sessionId, model, requestedModel, reasoningEffort, requestedReasoningEffort) {
|
|
2090
1641
|
const parts = [];
|
|
2091
1642
|
const normalizedModel = typeof model === "string" ? model.trim() : "";
|
|
@@ -2184,8 +1735,8 @@ export class CodexProvider {
|
|
|
2184
1735
|
case "item/started":
|
|
2185
1736
|
case "item/completed": {
|
|
2186
1737
|
const params = notification.method === "item/started"
|
|
2187
|
-
?
|
|
2188
|
-
:
|
|
1738
|
+
? asCodexItemStartedNotification(notification.params)
|
|
1739
|
+
: asCodexItemCompletedNotification(notification.params);
|
|
2189
1740
|
const item = params?.item && typeof params.item === "object"
|
|
2190
1741
|
? params.item
|
|
2191
1742
|
: null;
|
|
@@ -2224,7 +1775,7 @@ export class CodexProvider {
|
|
|
2224
1775
|
});
|
|
2225
1776
|
}
|
|
2226
1777
|
case "rawResponseItem/completed": {
|
|
2227
|
-
const params =
|
|
1778
|
+
const params = asCodexRawResponseItemCompletedNotification(notification.params);
|
|
2228
1779
|
const item = params?.item && typeof params.item === "object"
|
|
2229
1780
|
? params.item
|
|
2230
1781
|
: null;
|
|
@@ -2250,7 +1801,7 @@ export class CodexProvider {
|
|
|
2250
1801
|
});
|
|
2251
1802
|
}
|
|
2252
1803
|
case "turn/completed": {
|
|
2253
|
-
const params =
|
|
1804
|
+
const params = asCodexTurnCompletedNotification(notification.params);
|
|
2254
1805
|
return base({
|
|
2255
1806
|
sourceEvent: notification.method,
|
|
2256
1807
|
turnId: params?.turn.id,
|
|
@@ -2263,15 +1814,22 @@ export class CodexProvider {
|
|
|
2263
1814
|
});
|
|
2264
1815
|
}
|
|
2265
1816
|
case "error": {
|
|
2266
|
-
const params =
|
|
1817
|
+
const params = asCodexErrorNotification(notification.params);
|
|
2267
1818
|
const fallbackError = this.extractErrorRecord(notification.params);
|
|
1819
|
+
const rawParams = notification.params && typeof notification.params === "object"
|
|
1820
|
+
? notification.params
|
|
1821
|
+
: null;
|
|
1822
|
+
const willRetry = params?.willRetry ??
|
|
1823
|
+
(typeof rawParams?.willRetry === "boolean"
|
|
1824
|
+
? rawParams.willRetry
|
|
1825
|
+
: false);
|
|
2268
1826
|
const errorMessage = params?.error.message ??
|
|
2269
1827
|
this.getOptionalString(fallbackError?.message) ??
|
|
2270
1828
|
"Codex turn failed";
|
|
2271
1829
|
return base({
|
|
2272
1830
|
sourceEvent: notification.method,
|
|
2273
1831
|
turnId: params?.turnId,
|
|
2274
|
-
phase:
|
|
1832
|
+
phase: willRetry ? "retrying" : "terminal",
|
|
2275
1833
|
errorMessage,
|
|
2276
1834
|
codexErrorInfo: params?.error.codexErrorInfo ??
|
|
2277
1835
|
fallbackError?.codexErrorInfo ??
|
|
@@ -2422,7 +1980,7 @@ export class CodexProvider {
|
|
|
2422
1980
|
return `${trimmed.slice(0, CODEX_FAILURE_PREVIEW_CHARS)}...`;
|
|
2423
1981
|
}
|
|
2424
1982
|
extractTurnUsage(params) {
|
|
2425
|
-
const notification =
|
|
1983
|
+
const notification = asCodexThreadTokenUsageUpdatedNotification(params);
|
|
2426
1984
|
if (!notification)
|
|
2427
1985
|
return null;
|
|
2428
1986
|
return {
|
|
@@ -2679,7 +2237,7 @@ export class CodexProvider {
|
|
|
2679
2237
|
return [message];
|
|
2680
2238
|
}
|
|
2681
2239
|
case "turn/completed": {
|
|
2682
|
-
const params =
|
|
2240
|
+
const params = asCodexTurnCompletedNotification(notification.params);
|
|
2683
2241
|
const turnId = params?.turn.id ?? null;
|
|
2684
2242
|
const turnStatus = params?.turn.status;
|
|
2685
2243
|
const usage = turnId ? usageByTurnId.get(turnId) : undefined;
|
|
@@ -2756,20 +2314,37 @@ export class CodexProvider {
|
|
|
2756
2314
|
return messages;
|
|
2757
2315
|
}
|
|
2758
2316
|
case "error": {
|
|
2759
|
-
const params =
|
|
2760
|
-
const
|
|
2317
|
+
const params = asCodexErrorNotification(notification.params);
|
|
2318
|
+
const rawParams = notification.params && typeof notification.params === "object"
|
|
2319
|
+
? notification.params
|
|
2320
|
+
: null;
|
|
2321
|
+
const fallbackError = this.extractErrorRecord(notification.params);
|
|
2322
|
+
const errorMessage = params?.error.message ??
|
|
2323
|
+
this.getOptionalString(fallbackError?.message);
|
|
2324
|
+
const willRetry = params?.willRetry ??
|
|
2325
|
+
(typeof rawParams?.willRetry === "boolean"
|
|
2326
|
+
? rawParams.willRetry
|
|
2327
|
+
: false);
|
|
2328
|
+
const isProcessExit = rawParams?.codexProcessExit === true;
|
|
2761
2329
|
const message = (typeof errorMessage === "string" && errorMessage) ||
|
|
2762
|
-
(typeof
|
|
2763
|
-
|
|
2764
|
-
? notification.params.message
|
|
2330
|
+
(typeof rawParams?.message === "string"
|
|
2331
|
+
? rawParams.message
|
|
2765
2332
|
: "Codex turn failed");
|
|
2766
2333
|
const errorEvent = {
|
|
2767
2334
|
type: "error",
|
|
2335
|
+
uuid: params?.turnId
|
|
2336
|
+
? `codex-error-${params.turnId}`
|
|
2337
|
+
: `codex-error-${sessionId}-${Date.now()}`,
|
|
2768
2338
|
session_id: sessionId,
|
|
2769
2339
|
error: message,
|
|
2770
|
-
codexErrorInfo: params?.error.codexErrorInfo ??
|
|
2771
|
-
|
|
2772
|
-
|
|
2340
|
+
codexErrorInfo: params?.error.codexErrorInfo ??
|
|
2341
|
+
fallbackError?.codexErrorInfo ??
|
|
2342
|
+
null,
|
|
2343
|
+
codexAdditionalDetails: params?.error.additionalDetails ??
|
|
2344
|
+
this.getOptionalString(fallbackError?.additionalDetails) ??
|
|
2345
|
+
null,
|
|
2346
|
+
codexWillRetry: willRetry,
|
|
2347
|
+
codexErrorScope: isProcessExit ? "app_server_process" : "turn",
|
|
2773
2348
|
codexThreadId: params?.threadId,
|
|
2774
2349
|
codexTurnId: params?.turnId,
|
|
2775
2350
|
codexRequestId: this.extractOpenAIRequestId(notification.params, params?.error, message),
|
|
@@ -2784,8 +2359,8 @@ export class CodexProvider {
|
|
|
2784
2359
|
case "item/started":
|
|
2785
2360
|
case "item/completed": {
|
|
2786
2361
|
const params = notification.method === "item/started"
|
|
2787
|
-
?
|
|
2788
|
-
:
|
|
2362
|
+
? asCodexItemStartedNotification(notification.params)
|
|
2363
|
+
: asCodexItemCompletedNotification(notification.params);
|
|
2789
2364
|
if (!params)
|
|
2790
2365
|
return [];
|
|
2791
2366
|
const normalized = this.normalizeThreadItem(params.item);
|
|
@@ -2805,7 +2380,7 @@ export class CodexProvider {
|
|
|
2805
2380
|
return messages;
|
|
2806
2381
|
}
|
|
2807
2382
|
case "item/agentMessage/delta": {
|
|
2808
|
-
const params =
|
|
2383
|
+
const params = asCodexAgentMessageDeltaNotification(notification.params);
|
|
2809
2384
|
if (!params?.delta)
|
|
2810
2385
|
return [];
|
|
2811
2386
|
return [
|
|
@@ -2813,7 +2388,7 @@ export class CodexProvider {
|
|
|
2813
2388
|
];
|
|
2814
2389
|
}
|
|
2815
2390
|
case "item/plan/delta": {
|
|
2816
|
-
const params =
|
|
2391
|
+
const params = asCodexPlanDeltaNotification(notification.params);
|
|
2817
2392
|
if (!params?.delta)
|
|
2818
2393
|
return [];
|
|
2819
2394
|
return [
|
|
@@ -2821,7 +2396,7 @@ export class CodexProvider {
|
|
|
2821
2396
|
];
|
|
2822
2397
|
}
|
|
2823
2398
|
case "item/reasoning/summaryTextDelta": {
|
|
2824
|
-
const params =
|
|
2399
|
+
const params = asCodexReasoningSummaryTextDeltaNotification(notification.params);
|
|
2825
2400
|
if (!params?.delta)
|
|
2826
2401
|
return [];
|
|
2827
2402
|
return [
|
|
@@ -2829,7 +2404,7 @@ export class CodexProvider {
|
|
|
2829
2404
|
];
|
|
2830
2405
|
}
|
|
2831
2406
|
case "item/commandExecution/outputDelta": {
|
|
2832
|
-
const params =
|
|
2407
|
+
const params = asCodexCommandExecutionOutputDeltaNotification(notification.params);
|
|
2833
2408
|
if (!params?.delta)
|
|
2834
2409
|
return [];
|
|
2835
2410
|
return [
|
|
@@ -2837,7 +2412,7 @@ export class CodexProvider {
|
|
|
2837
2412
|
];
|
|
2838
2413
|
}
|
|
2839
2414
|
case "item/fileChange/outputDelta": {
|
|
2840
|
-
const params =
|
|
2415
|
+
const params = asCodexFileChangeOutputDeltaNotification(notification.params);
|
|
2841
2416
|
if (!params?.delta)
|
|
2842
2417
|
return [];
|
|
2843
2418
|
return [
|
|
@@ -2845,7 +2420,7 @@ export class CodexProvider {
|
|
|
2845
2420
|
];
|
|
2846
2421
|
}
|
|
2847
2422
|
case "rawResponseItem/completed": {
|
|
2848
|
-
const params =
|
|
2423
|
+
const params = asCodexRawResponseItemCompletedNotification(notification.params);
|
|
2849
2424
|
if (!params)
|
|
2850
2425
|
return [];
|
|
2851
2426
|
return this.convertRawResponseItemToSDKMessages(params, sessionId, liveEventState);
|
|
@@ -2885,6 +2460,7 @@ export class CodexProvider {
|
|
|
2885
2460
|
: Array.isArray(itemRecord.command_actions)
|
|
2886
2461
|
? itemRecord.command_actions
|
|
2887
2462
|
: undefined) ?? undefined;
|
|
2463
|
+
const cwd = this.getOptionalString(itemRecord.cwd);
|
|
2888
2464
|
return {
|
|
2889
2465
|
id,
|
|
2890
2466
|
type: "command_execution",
|
|
@@ -2895,7 +2471,11 @@ export class CodexProvider {
|
|
|
2895
2471
|
exit_code: this.getOptionalNumber(itemRecord.exit_code) ??
|
|
2896
2472
|
this.getOptionalNumber(itemRecord.exitCode) ??
|
|
2897
2473
|
undefined,
|
|
2474
|
+
durationMs: this.getOptionalNumber(itemRecord.duration_ms) ??
|
|
2475
|
+
this.getOptionalNumber(itemRecord.durationMs) ??
|
|
2476
|
+
undefined,
|
|
2898
2477
|
status: this.normalizeStatus(itemRecord.status),
|
|
2478
|
+
...(cwd ? { cwd } : {}),
|
|
2899
2479
|
...(commandActions ? { commandActions } : {}),
|
|
2900
2480
|
};
|
|
2901
2481
|
}
|
|
@@ -3072,52 +2652,6 @@ export class CodexProvider {
|
|
|
3072
2652
|
return "unknown";
|
|
3073
2653
|
return status.replace(/[A-Z]/g, (m) => `_${m.toLowerCase()}`);
|
|
3074
2654
|
}
|
|
3075
|
-
asTurnCompletedNotification(params) {
|
|
3076
|
-
if (!params || typeof params !== "object")
|
|
3077
|
-
return null;
|
|
3078
|
-
const record = params;
|
|
3079
|
-
if (typeof record.threadId !== "string" ||
|
|
3080
|
-
!record.turn ||
|
|
3081
|
-
typeof record.turn !== "object" ||
|
|
3082
|
-
typeof record.turn.id !== "string") {
|
|
3083
|
-
return null;
|
|
3084
|
-
}
|
|
3085
|
-
return params;
|
|
3086
|
-
}
|
|
3087
|
-
asErrorNotification(params) {
|
|
3088
|
-
if (!params || typeof params !== "object")
|
|
3089
|
-
return null;
|
|
3090
|
-
const record = params;
|
|
3091
|
-
if (typeof record.threadId !== "string" ||
|
|
3092
|
-
typeof record.turnId !== "string" ||
|
|
3093
|
-
typeof record.willRetry !== "boolean" ||
|
|
3094
|
-
!record.error ||
|
|
3095
|
-
typeof record.error !== "object" ||
|
|
3096
|
-
typeof record.error.message !== "string") {
|
|
3097
|
-
return null;
|
|
3098
|
-
}
|
|
3099
|
-
return params;
|
|
3100
|
-
}
|
|
3101
|
-
asThreadTokenUsageUpdatedNotification(params) {
|
|
3102
|
-
if (!params || typeof params !== "object")
|
|
3103
|
-
return null;
|
|
3104
|
-
const record = params;
|
|
3105
|
-
const tokenUsage = record.tokenUsage && typeof record.tokenUsage === "object"
|
|
3106
|
-
? record.tokenUsage
|
|
3107
|
-
: null;
|
|
3108
|
-
const last = tokenUsage?.last && typeof tokenUsage.last === "object"
|
|
3109
|
-
? tokenUsage.last
|
|
3110
|
-
: null;
|
|
3111
|
-
if (typeof record.threadId !== "string" ||
|
|
3112
|
-
typeof record.turnId !== "string" ||
|
|
3113
|
-
!last ||
|
|
3114
|
-
typeof last.inputTokens !== "number" ||
|
|
3115
|
-
typeof last.outputTokens !== "number" ||
|
|
3116
|
-
typeof last.cachedInputTokens !== "number") {
|
|
3117
|
-
return null;
|
|
3118
|
-
}
|
|
3119
|
-
return params;
|
|
3120
|
-
}
|
|
3121
2655
|
asCommandExecutionRequestApprovalParams(params) {
|
|
3122
2656
|
if (!params || typeof params !== "object")
|
|
3123
2657
|
return null;
|
|
@@ -3166,116 +2700,17 @@ export class CodexProvider {
|
|
|
3166
2700
|
}
|
|
3167
2701
|
return params;
|
|
3168
2702
|
}
|
|
3169
|
-
asItemStartedNotification(params) {
|
|
3170
|
-
if (!params || typeof params !== "object")
|
|
3171
|
-
return null;
|
|
3172
|
-
const record = params;
|
|
3173
|
-
if (typeof record.threadId !== "string" ||
|
|
3174
|
-
typeof record.turnId !== "string" ||
|
|
3175
|
-
!record.item ||
|
|
3176
|
-
typeof record.item !== "object") {
|
|
3177
|
-
return null;
|
|
3178
|
-
}
|
|
3179
|
-
return params;
|
|
3180
|
-
}
|
|
3181
|
-
asItemCompletedNotification(params) {
|
|
3182
|
-
if (!params || typeof params !== "object")
|
|
3183
|
-
return null;
|
|
3184
|
-
const record = params;
|
|
3185
|
-
if (typeof record.threadId !== "string" ||
|
|
3186
|
-
typeof record.turnId !== "string" ||
|
|
3187
|
-
!record.item ||
|
|
3188
|
-
typeof record.item !== "object") {
|
|
3189
|
-
return null;
|
|
3190
|
-
}
|
|
3191
|
-
return params;
|
|
3192
|
-
}
|
|
3193
|
-
asAgentMessageDeltaNotification(params) {
|
|
3194
|
-
if (!params || typeof params !== "object")
|
|
3195
|
-
return null;
|
|
3196
|
-
const record = params;
|
|
3197
|
-
if (typeof record.threadId !== "string" ||
|
|
3198
|
-
typeof record.turnId !== "string" ||
|
|
3199
|
-
typeof record.itemId !== "string" ||
|
|
3200
|
-
typeof record.delta !== "string") {
|
|
3201
|
-
return null;
|
|
3202
|
-
}
|
|
3203
|
-
return params;
|
|
3204
|
-
}
|
|
3205
|
-
asPlanDeltaNotification(params) {
|
|
3206
|
-
if (!params || typeof params !== "object")
|
|
3207
|
-
return null;
|
|
3208
|
-
const record = params;
|
|
3209
|
-
if (typeof record.threadId !== "string" ||
|
|
3210
|
-
typeof record.turnId !== "string" ||
|
|
3211
|
-
typeof record.itemId !== "string" ||
|
|
3212
|
-
typeof record.delta !== "string") {
|
|
3213
|
-
return null;
|
|
3214
|
-
}
|
|
3215
|
-
return params;
|
|
3216
|
-
}
|
|
3217
|
-
asReasoningSummaryTextDeltaNotification(params) {
|
|
3218
|
-
if (!params || typeof params !== "object")
|
|
3219
|
-
return null;
|
|
3220
|
-
const record = params;
|
|
3221
|
-
if (typeof record.threadId !== "string" ||
|
|
3222
|
-
typeof record.turnId !== "string" ||
|
|
3223
|
-
typeof record.itemId !== "string" ||
|
|
3224
|
-
typeof record.delta !== "string" ||
|
|
3225
|
-
typeof record.summaryIndex !== "number") {
|
|
3226
|
-
return null;
|
|
3227
|
-
}
|
|
3228
|
-
return params;
|
|
3229
|
-
}
|
|
3230
|
-
asCommandExecutionOutputDeltaNotification(params) {
|
|
3231
|
-
if (!params || typeof params !== "object")
|
|
3232
|
-
return null;
|
|
3233
|
-
const record = params;
|
|
3234
|
-
if (typeof record.threadId !== "string" ||
|
|
3235
|
-
typeof record.turnId !== "string" ||
|
|
3236
|
-
typeof record.itemId !== "string" ||
|
|
3237
|
-
typeof record.delta !== "string") {
|
|
3238
|
-
return null;
|
|
3239
|
-
}
|
|
3240
|
-
return params;
|
|
3241
|
-
}
|
|
3242
|
-
asFileChangeOutputDeltaNotification(params) {
|
|
3243
|
-
if (!params || typeof params !== "object")
|
|
3244
|
-
return null;
|
|
3245
|
-
const record = params;
|
|
3246
|
-
if (typeof record.threadId !== "string" ||
|
|
3247
|
-
typeof record.turnId !== "string" ||
|
|
3248
|
-
typeof record.itemId !== "string" ||
|
|
3249
|
-
typeof record.delta !== "string") {
|
|
3250
|
-
return null;
|
|
3251
|
-
}
|
|
3252
|
-
return params;
|
|
3253
|
-
}
|
|
3254
|
-
asRawResponseItemCompletedNotification(params) {
|
|
3255
|
-
if (!params || typeof params !== "object")
|
|
3256
|
-
return null;
|
|
3257
|
-
const record = params;
|
|
3258
|
-
if (typeof record.threadId !== "string" ||
|
|
3259
|
-
typeof record.turnId !== "string" ||
|
|
3260
|
-
!record.item ||
|
|
3261
|
-
typeof record.item !== "object" ||
|
|
3262
|
-
typeof record.item.type !== "string") {
|
|
3263
|
-
return null;
|
|
3264
|
-
}
|
|
3265
|
-
return params;
|
|
3266
|
-
}
|
|
3267
2703
|
buildItemEventKey(turnId, itemId) {
|
|
3268
2704
|
return `${turnId}:${itemId}`;
|
|
3269
2705
|
}
|
|
3270
2706
|
buildItemMessageUuid(turnId, itemId) {
|
|
3271
2707
|
return `${itemId}-${turnId}`;
|
|
3272
2708
|
}
|
|
3273
|
-
//
|
|
3274
|
-
//
|
|
3275
|
-
//
|
|
3276
|
-
//
|
|
3277
|
-
//
|
|
3278
|
-
// topics/stream-durable-id-dedup.md (Codex tool calls).
|
|
2709
|
+
// Native tool thread items carry Codex's globally-unique call_id as item.id,
|
|
2710
|
+
// so this uuid aligns directly with the durable response item. A code-mode
|
|
2711
|
+
// commandExecution instead carries an inner exec-* id while rollout stores
|
|
2712
|
+
// the outer call_* id; the client reconciles that scoped exception via
|
|
2713
|
+
// _codexToolCorrelation. See topics/stream-durable-id-dedup.md.
|
|
3279
2714
|
buildItemToolUuid(callId) {
|
|
3280
2715
|
return callId;
|
|
3281
2716
|
}
|
|
@@ -3373,6 +2808,11 @@ export class CodexProvider {
|
|
|
3373
2808
|
session_id: sessionId,
|
|
3374
2809
|
uuid: this.buildItemResultUuid(itemId),
|
|
3375
2810
|
_isStreaming: true,
|
|
2811
|
+
...(sourceEvent === "command_output_delta"
|
|
2812
|
+
? {
|
|
2813
|
+
[CODEX_TOOL_CORRELATION_FIELD]: createCodexToolCorrelation("command_execution", turnId, itemId),
|
|
2814
|
+
}
|
|
2815
|
+
: {}),
|
|
3376
2816
|
message: {
|
|
3377
2817
|
role: "user",
|
|
3378
2818
|
content: [
|
|
@@ -3433,6 +2873,9 @@ export class CodexProvider {
|
|
|
3433
2873
|
id: callId,
|
|
3434
2874
|
name: normalizedInvocation.toolName,
|
|
3435
2875
|
input: normalizedInvocation.input,
|
|
2876
|
+
...(normalizedInvocation.displayActions
|
|
2877
|
+
? { _displayActions: normalizedInvocation.displayActions }
|
|
2878
|
+
: {}),
|
|
3436
2879
|
},
|
|
3437
2880
|
],
|
|
3438
2881
|
},
|
|
@@ -3493,7 +2936,7 @@ export class CodexProvider {
|
|
|
3493
2936
|
const input = this.getOptionalString(item.input);
|
|
3494
2937
|
if (!callId || !rawToolName)
|
|
3495
2938
|
return [];
|
|
3496
|
-
const normalizedInvocation =
|
|
2939
|
+
const normalizedInvocation = normalizeCodexCustomToolInvocation(rawToolName, input ?? "");
|
|
3497
2940
|
liveEventState.toolCallContexts.set(callId, {
|
|
3498
2941
|
toolName: normalizedInvocation.toolName,
|
|
3499
2942
|
input: normalizedInvocation.input,
|
|
@@ -3505,6 +2948,7 @@ export class CodexProvider {
|
|
|
3505
2948
|
type: "assistant",
|
|
3506
2949
|
session_id: sessionId,
|
|
3507
2950
|
uuid: this.buildItemToolUuid(callId),
|
|
2951
|
+
[CODEX_TOOL_CORRELATION_FIELD]: createCodexToolCorrelation("custom_tool_call", params.turnId, callId),
|
|
3508
2952
|
message: {
|
|
3509
2953
|
role: "assistant",
|
|
3510
2954
|
content: [
|
|
@@ -3513,6 +2957,9 @@ export class CodexProvider {
|
|
|
3513
2957
|
id: callId,
|
|
3514
2958
|
name: normalizedInvocation.toolName,
|
|
3515
2959
|
input: normalizedInvocation.input,
|
|
2960
|
+
...(normalizedInvocation.displayActions
|
|
2961
|
+
? { _displayActions: normalizedInvocation.displayActions }
|
|
2962
|
+
: {}),
|
|
3516
2963
|
},
|
|
3517
2964
|
],
|
|
3518
2965
|
},
|
|
@@ -3549,6 +2996,7 @@ export class CodexProvider {
|
|
|
3549
2996
|
type: "user",
|
|
3550
2997
|
session_id: sessionId,
|
|
3551
2998
|
uuid: this.buildItemResultUuid(callId),
|
|
2999
|
+
[CODEX_TOOL_CORRELATION_FIELD]: createCodexToolCorrelation("custom_tool_call", params.turnId, callId),
|
|
3552
3000
|
message: {
|
|
3553
3001
|
role: "user",
|
|
3554
3002
|
content: [toolResult],
|
|
@@ -3594,9 +3042,10 @@ export class CodexProvider {
|
|
|
3594
3042
|
convertItemToSDKMessages(item, sessionId, turnId, sourceEvent) {
|
|
3595
3043
|
const isComplete = sourceEvent === "item/completed";
|
|
3596
3044
|
const observedAt = new Date().toISOString();
|
|
3597
|
-
//
|
|
3598
|
-
//
|
|
3599
|
-
//
|
|
3045
|
+
// Native tool items key the uuid on call_id (item.id). Code-mode
|
|
3046
|
+
// commandExecution items temporarily key on exec-* and carry correlation
|
|
3047
|
+
// metadata for adoption of the outer durable call_* id client-side.
|
|
3048
|
+
// Message/reasoning counters have no durable equivalent and stay scoped.
|
|
3600
3049
|
const uuid = this.isToolBackedThreadItem(item)
|
|
3601
3050
|
? this.buildItemToolUuid(item.id)
|
|
3602
3051
|
: `${item.id}-${turnId}`;
|
|
@@ -3646,10 +3095,13 @@ export class CodexProvider {
|
|
|
3646
3095
|
}
|
|
3647
3096
|
case "command_execution": {
|
|
3648
3097
|
const messages = [];
|
|
3649
|
-
const
|
|
3650
|
-
|
|
3651
|
-
|
|
3652
|
-
|
|
3098
|
+
const correlationStartedAt = item.durationMs !== undefined
|
|
3099
|
+
? new Date(Date.parse(observedAt) - Math.max(0, item.durationMs)).toISOString()
|
|
3100
|
+
: observedAt;
|
|
3101
|
+
const normalizedInvocation = normalizeCodexToolInvocation("Bash", {
|
|
3102
|
+
command: item.command,
|
|
3103
|
+
...(item.cwd ? { cwd: item.cwd } : {}),
|
|
3104
|
+
});
|
|
3653
3105
|
const toolContext = {
|
|
3654
3106
|
toolName: normalizedInvocation.toolName,
|
|
3655
3107
|
input: normalizedInvocation.input,
|
|
@@ -3661,6 +3113,7 @@ export class CodexProvider {
|
|
|
3661
3113
|
type: "assistant",
|
|
3662
3114
|
session_id: sessionId,
|
|
3663
3115
|
uuid,
|
|
3116
|
+
[CODEX_TOOL_CORRELATION_FIELD]: createCodexToolCorrelation("command_execution", turnId, item.id, correlationStartedAt),
|
|
3664
3117
|
message: {
|
|
3665
3118
|
role: "assistant",
|
|
3666
3119
|
content: [
|
|
@@ -3669,6 +3122,9 @@ export class CodexProvider {
|
|
|
3669
3122
|
id: item.id,
|
|
3670
3123
|
name: normalizedInvocation.toolName,
|
|
3671
3124
|
input: normalizedInvocation.input,
|
|
3125
|
+
...(normalizedInvocation.displayActions
|
|
3126
|
+
? { _displayActions: normalizedInvocation.displayActions }
|
|
3127
|
+
: {}),
|
|
3672
3128
|
},
|
|
3673
3129
|
],
|
|
3674
3130
|
},
|
|
@@ -3702,6 +3158,7 @@ export class CodexProvider {
|
|
|
3702
3158
|
type: "user",
|
|
3703
3159
|
session_id: sessionId,
|
|
3704
3160
|
uuid: `${uuid}-result`,
|
|
3161
|
+
[CODEX_TOOL_CORRELATION_FIELD]: createCodexToolCorrelation("command_execution", turnId, item.id, correlationStartedAt),
|
|
3705
3162
|
message: {
|
|
3706
3163
|
role: "user",
|
|
3707
3164
|
content: [toolResultBlock],
|