@openclaw/codex 2026.7.2-beta.7 → 2026.8.1-beta.3
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/README.md +2 -0
- package/dist/api.js +147 -0
- package/dist/app-server-policy-bg5QPSVP.js +25 -0
- package/dist/attempt-client-cleanup-URjUlCHg.js +735 -0
- package/dist/binding-connection-DAvZwp96.js +45 -0
- package/dist/{bounded-turn-D2ZAgZVz.js → bounded-turn-4BjrZEwW.js} +63 -56
- package/dist/{capabilities-BFDTVYr4.js → capabilities-CH3K57v4.js} +8 -2
- package/dist/cli-metadata.js +1 -1
- package/dist/{command-formatters-C336eRVS.js → command-formatters-D0nZ3qtd.js} +18 -18
- package/dist/{command-handlers-DAHUSry9.js → command-handlers-DC86lgT4.js} +507 -101
- package/dist/command-rpc-xUIIonsO.js +90 -0
- package/dist/{compact-D_uvHurS.js → compact-COqgBRny.js} +234 -214
- package/dist/{session-binding-BXpo9ymA.js → config-CpNeo5AE.js} +284 -1163
- package/dist/context-compaction-activity-BOeJf7yo.js +58 -0
- package/dist/{conversation-binding-data-BHRpYbX3.js → conversation-binding-data-CW2GuupV.js} +6 -10
- package/dist/doctor-contract-api.js +48 -50
- package/dist/{dynamic-tools-D2gYkSBO.js → dynamic-tools-fJZhl4CE.js} +3442 -1433
- package/dist/{effective-mcp-catalog-Bbd98Inw.js → effective-mcp-catalog-4YKn51aG.js} +20 -15
- package/dist/elicitation-input-DMkeki8d.js +71 -0
- package/dist/{event-projector-assistant-message-DTgnPPVF.js → event-projector-assistant-message-BwxV4d6N.js} +11 -23
- package/dist/{attempt-notifications-AP-a-Q5k.js → event-projector-usage-CLwNEJqW.js} +113 -29
- package/dist/harness-DoKQcF8n.js +258 -0
- package/dist/harness.js +2 -160
- package/dist/image-payload-sanitizer-CnfoUPCE.js +65 -0
- package/dist/index.js +730 -256
- package/dist/isolated-completion-DPMtlH9r.js +75 -0
- package/dist/local-runtime-attribution-B_2mnqhb.js +19 -0
- package/dist/managed-binary-By4FZC6i.js +212 -0
- package/dist/media-understanding-provider.js +5 -5
- package/dist/model-catalog-CmGoqVKB.js +48 -0
- package/dist/{models-BBMKU4jA.js → models-CZw1wClT.js} +12 -17
- package/dist/native-subagent-monitor-GGq3RnOo.js +3225 -0
- package/dist/node-exec-server.runtime-Bsu1LdFZ.js +192 -0
- package/dist/{plugin-app-cache-key-DztPafOA.js → plugin-app-cache-key-DMNQ8Zi8.js} +18 -6
- package/dist/plugin-approval-roundtrip-C75Yiiwc.js +95 -0
- package/dist/plugin-marketplace-discovery-CSWDkMrP.js +399 -0
- package/dist/{computer-use-CYEc8U3w.js → plugin-metadata-cache-BXH5NF-4.js} +109 -6
- package/dist/protocol-validators-VAVyEnDp.js +2399 -0
- package/dist/{rate-limits-CU-gVCCS.js → rate-limits-BI1dMHDG.js} +17 -35
- package/dist/{request-qKh331yu.js → request-DSK0W6YI.js} +3 -3
- package/dist/{run-attempt-CY9WlDLc.js → run-attempt-BV3HzuCf.js} +3416 -7194
- package/dist/{runtime-artifact-CmtG_t1L.js → runtime-artifact-BvyT1uyd.js} +11 -29
- package/dist/{sandbox-guard-NuhpXmPB.js → sandbox-guard-C1qEeZ5C.js} +29 -30
- package/dist/session-binding-BTrLf9Qm.js +874 -0
- package/dist/{session-catalog-DyOgR4WH.js → session-catalog-ezP_UcRM.js} +1584 -1289
- package/dist/session-catalog-home-id-BNwAJ9D7.js +18 -0
- package/dist/{session-cli-2PZaFLRh.js → session-cli-B1hKvfkI.js} +20 -7
- package/dist/session-retirement-CE4iMiLh.js +36 -0
- package/dist/{session-upstream-marker-B6U7tLw5.js → session-upstream-marker-D_2npHlA.js} +1 -1
- package/dist/{settled-turn-finalizer-CXY2Z9dT.js → settled-turn-finalizer-Dx1onIqg.js} +40 -28
- package/dist/{shared-client-DTbvH-XV.js → shared-client-Dw-rzii0.js} +1315 -469
- package/dist/{side-question-_ulBk1AL.js → side-question-DbXkJZzg.js} +140 -69
- package/dist/{thread-lifecycle-DF53ogiA.js → thread-lifecycle-DKdrnTMX.js} +927 -768
- package/dist/thread-ownership-i2NBwDUL.js +92 -0
- package/dist/thread-resume-CdJk2Ehf.js +30 -0
- package/dist/transcript-mirror-BU0_LKAL.js +588 -0
- package/dist/{transport-stdio-DXgGZ7Ib.js → transport-stdio-DhoGy33Z.js} +13 -2
- package/dist/upstream-prompt-provenance-CFmsKwr9.js +39 -0
- package/dist/{upstream-session-fork-Dy4Xvuoj.js → upstream-session-fork-BDVJCLAD.js} +14 -8
- package/dist/{usage-CQ6GhD5-.js → usage-9dKJCgcy.js} +3 -3
- package/dist/{web-search-provider.runtime-CCFhg2z5.js → web-search-provider.runtime-DCdx4DGu.js} +8 -9
- package/openclaw.plugin.json +49 -4
- package/package.json +6 -5
- package/dist/app-server-policy-BSaO2JIT.js +0 -49
- package/dist/conversation-control-xsIeXbo4.js +0 -287
- package/dist/event-projector-usage-Xp4AlR2k.js +0 -86
- package/dist/notification-correlation-CU6_AnOb.js +0 -67
- package/dist/transcript-mirror-DzsdNCf5.js +0 -6924
|
@@ -1,25 +1,21 @@
|
|
|
1
|
-
import { d as retainSharedCodexAppServerClientByInstanceId } from "./shared-client-
|
|
2
|
-
import { d as sessionBindingIdentity } from "./session-binding-
|
|
1
|
+
import { d as retainSharedCodexAppServerClientByInstanceId } from "./shared-client-Dw-rzii0.js";
|
|
2
|
+
import { d as sessionBindingIdentity } from "./session-binding-BTrLf9Qm.js";
|
|
3
|
+
import { asOptionalRecord, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
3
4
|
import { assignMcpCatalogSafeServerNames } from "openclaw/plugin-sdk/agent-harness-runtime";
|
|
4
5
|
//#region extensions/codex/src/app-server/effective-mcp-catalog.ts
|
|
5
6
|
const MCP_STATUS_PAGE_SIZE = 100;
|
|
6
7
|
const MCP_STATUS_MAX_PAGES = 100;
|
|
7
|
-
function asRecord(value) {
|
|
8
|
-
return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
9
|
-
}
|
|
10
|
-
function readString(value) {
|
|
11
|
-
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
12
|
-
}
|
|
13
8
|
function catalogTool(params) {
|
|
14
|
-
const raw =
|
|
15
|
-
const description =
|
|
9
|
+
const raw = asOptionalRecord(params.raw);
|
|
10
|
+
const description = normalizeOptionalString(raw?.description);
|
|
11
|
+
const title = normalizeOptionalString(raw?.title);
|
|
16
12
|
return {
|
|
17
13
|
serverName: params.serverName,
|
|
18
14
|
safeServerName: params.safeServerName,
|
|
19
15
|
toolName: params.toolName,
|
|
20
|
-
...
|
|
16
|
+
...title ? { title } : {},
|
|
21
17
|
...description ? { description } : {},
|
|
22
|
-
inputSchema:
|
|
18
|
+
inputSchema: asOptionalRecord(raw?.inputSchema) ?? { type: "object" },
|
|
23
19
|
fallbackDescription: description ?? params.toolName,
|
|
24
20
|
...params.deniedBySession ? { deniedBySession: true } : {}
|
|
25
21
|
};
|
|
@@ -92,7 +88,12 @@ async function listCodexMcpServerStatuses(client, threadId) {
|
|
|
92
88
|
}
|
|
93
89
|
throw new Error("Codex mcpServerStatus/list exceeded the bounded page limit");
|
|
94
90
|
}
|
|
95
|
-
/** Loads MCP inventory
|
|
91
|
+
/** Loads the requested MCP inventory from the exact client/thread already selected for a run. */
|
|
92
|
+
async function loadCodexEffectiveMcpCatalogFromThread(params) {
|
|
93
|
+
const allowedServerNames = new Set(params.mcpServerNames);
|
|
94
|
+
return buildCodexEffectiveMcpCatalog((await listCodexMcpServerStatuses(params.client, params.threadId)).filter((status) => allowedServerNames.has(status.name)), params.toolOverrides);
|
|
95
|
+
}
|
|
96
|
+
/** Loads MCP inventory from the bound Codex client while retaining its lease through all pages. */
|
|
96
97
|
async function loadCodexEffectiveMcpCatalog(params, options) {
|
|
97
98
|
const binding = await options.bindingStore.read(sessionBindingIdentity({
|
|
98
99
|
agentId: params.agentId,
|
|
@@ -104,8 +105,12 @@ async function loadCodexEffectiveMcpCatalog(params, options) {
|
|
|
104
105
|
const retained = retainSharedCodexAppServerClientByInstanceId(binding.clientId);
|
|
105
106
|
if (!retained) return;
|
|
106
107
|
try {
|
|
107
|
-
|
|
108
|
-
|
|
108
|
+
return await loadCodexEffectiveMcpCatalogFromThread({
|
|
109
|
+
client: retained.client,
|
|
110
|
+
threadId: binding.threadId,
|
|
111
|
+
mcpServerNames: params.mcpServerNames,
|
|
112
|
+
toolOverrides: params.toolOverrides
|
|
113
|
+
});
|
|
109
114
|
} finally {
|
|
110
115
|
retained.release();
|
|
111
116
|
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { agentHarnessStructuredInput } from "openclaw/plugin-sdk/agent-harness-runtime";
|
|
2
|
+
//#region extensions/codex/src/app-server/elicitation-input.ts
|
|
3
|
+
/** Snapshots and compiles ordinary Codex input before it enters the per-turn queue. */
|
|
4
|
+
function compileCodexOrdinaryElicitation(params) {
|
|
5
|
+
if (readRawOwnString(params.value, "threadId") !== params.threadId) return { kind: "ignored" };
|
|
6
|
+
const snapshot = agentHarnessStructuredInput.snapshot(params.value);
|
|
7
|
+
if (!agentHarnessStructuredInput.isRecord(snapshot)) return {
|
|
8
|
+
kind: "compiled",
|
|
9
|
+
input: {
|
|
10
|
+
kind: "unsupported",
|
|
11
|
+
message: "OpenClaw declined a malformed or over-limit MCP elicitation request."
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
const requestTurnId = readValue(snapshot, "turnId");
|
|
15
|
+
if (typeof requestTurnId === "string" && requestTurnId !== params.turnId) return { kind: "ignored" };
|
|
16
|
+
if (requestTurnId !== null && typeof requestTurnId !== "string") return {
|
|
17
|
+
kind: "compiled",
|
|
18
|
+
input: {
|
|
19
|
+
kind: "unsupported",
|
|
20
|
+
message: "OpenClaw declined an MCP elicitation with invalid turn correlation."
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
const mode = readCodexElicitationString(snapshot, "mode");
|
|
24
|
+
if (mode === "url") return {
|
|
25
|
+
kind: "compiled",
|
|
26
|
+
input: agentHarnessStructuredInput.compileUrl({
|
|
27
|
+
url: readValue(snapshot, "url"),
|
|
28
|
+
elicitationId: readValue(snapshot, "elicitationId"),
|
|
29
|
+
message: readValue(snapshot, "message"),
|
|
30
|
+
fallbackMessage: "Codex provided a URL",
|
|
31
|
+
protocolName: "MCP"
|
|
32
|
+
})
|
|
33
|
+
};
|
|
34
|
+
if (mode !== "form" && mode !== "openai/form") return {
|
|
35
|
+
kind: "compiled",
|
|
36
|
+
input: {
|
|
37
|
+
kind: "unsupported",
|
|
38
|
+
message: `OpenClaw does not support MCP elicitation mode ${JSON.stringify(mode ?? "unknown")}.`
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
return {
|
|
42
|
+
kind: "compiled",
|
|
43
|
+
input: agentHarnessStructuredInput.compileForm({
|
|
44
|
+
schema: readValue(snapshot, "requestedSchema"),
|
|
45
|
+
message: readCodexElicitationString(snapshot, "message"),
|
|
46
|
+
fallbackMessage: "Codex needs input",
|
|
47
|
+
options: {
|
|
48
|
+
protocolName: mode === "openai/form" ? "OpenAI" : "MCP",
|
|
49
|
+
allowEmptyForm: true,
|
|
50
|
+
minimumChoiceCount: 1,
|
|
51
|
+
allowEnumNames: true,
|
|
52
|
+
allowImagePicker: mode === "openai/form",
|
|
53
|
+
metadata: { secretPath: ["isSecret"] }
|
|
54
|
+
}
|
|
55
|
+
})
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
function readValue(record, key) {
|
|
59
|
+
return Object.hasOwn(record, key) ? record[key] : void 0;
|
|
60
|
+
}
|
|
61
|
+
function readCodexElicitationString(record, key) {
|
|
62
|
+
const value = readValue(record, key);
|
|
63
|
+
return typeof value === "string" ? value : void 0;
|
|
64
|
+
}
|
|
65
|
+
function readRawOwnString(value, key) {
|
|
66
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return;
|
|
67
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
68
|
+
return descriptor && "value" in descriptor && typeof descriptor.value === "string" ? descriptor.value : void 0;
|
|
69
|
+
}
|
|
70
|
+
//#endregion
|
|
71
|
+
export { compileCodexOrdinaryElicitation };
|
|
@@ -1,24 +1,5 @@
|
|
|
1
|
+
import { t as resolveCodexLocalRuntimeAttribution } from "./local-runtime-attribution-B_2mnqhb.js";
|
|
1
2
|
import { formatErrorMessage } from "openclaw/plugin-sdk/agent-harness-runtime";
|
|
2
|
-
//#region extensions/codex/src/app-server/local-runtime-attribution.ts
|
|
3
|
-
const OPENAI_PROVIDER_ID = "openai";
|
|
4
|
-
const OPENAI_RESPONSES_API = "openai-responses";
|
|
5
|
-
const OPENAI_CODEX_RESPONSES_API = "openai-chatgpt-responses";
|
|
6
|
-
function normalizeRuntimeId(value) {
|
|
7
|
-
return value?.trim().toLowerCase() ?? "";
|
|
8
|
-
}
|
|
9
|
-
/** Maps local Codex runtime plans onto the provider/api pair exposed to event projection. */
|
|
10
|
-
function resolveCodexLocalRuntimeAttribution(params) {
|
|
11
|
-
const authProfileProvider = normalizeRuntimeId(params.runtimePlan?.auth?.authProfileProviderForAuth);
|
|
12
|
-
if (normalizeRuntimeId(params.runtimePlan?.observability.harnessId) === "codex" && authProfileProvider !== OPENAI_PROVIDER_ID && normalizeRuntimeId(params.model.provider) === OPENAI_PROVIDER_ID && normalizeRuntimeId(params.model.api) === OPENAI_RESPONSES_API) return {
|
|
13
|
-
provider: OPENAI_PROVIDER_ID,
|
|
14
|
-
api: OPENAI_CODEX_RESPONSES_API
|
|
15
|
-
};
|
|
16
|
-
return {
|
|
17
|
-
provider: params.provider,
|
|
18
|
-
api: params.model.api
|
|
19
|
-
};
|
|
20
|
-
}
|
|
21
|
-
//#endregion
|
|
22
3
|
//#region extensions/codex/src/app-server/event-projector-assistant-message.ts
|
|
23
4
|
const ZERO_USAGE = {
|
|
24
5
|
input: 0,
|
|
@@ -35,12 +16,19 @@ const ZERO_USAGE = {
|
|
|
35
16
|
}
|
|
36
17
|
};
|
|
37
18
|
function createAssistantMessage(params, text, options) {
|
|
38
|
-
|
|
19
|
+
return createAttributedCodexAssistantMessage({
|
|
20
|
+
...resolveCodexLocalRuntimeAttribution(params),
|
|
21
|
+
modelId: params.modelId
|
|
22
|
+
}, text, options);
|
|
23
|
+
}
|
|
24
|
+
/** Creates a Codex assistant row when a bounded call already owns attribution. */
|
|
25
|
+
function createAttributedCodexAssistantMessage(attribution, text, options) {
|
|
39
26
|
const usage = options.tokenUsage ? {
|
|
40
27
|
input: options.tokenUsage.input ?? 0,
|
|
41
28
|
output: options.tokenUsage.output ?? 0,
|
|
42
29
|
cacheRead: options.tokenUsage.cacheRead ?? 0,
|
|
43
30
|
cacheWrite: options.tokenUsage.cacheWrite ?? 0,
|
|
31
|
+
...options.tokenUsage.reasoningTokens !== void 0 ? { reasoningTokens: options.tokenUsage.reasoningTokens } : {},
|
|
44
32
|
...options.tokenUsage.contextUsage ? { contextUsage: options.tokenUsage.contextUsage } : {},
|
|
45
33
|
totalTokens: options.tokenUsage.total ?? (options.tokenUsage.input ?? 0) + (options.tokenUsage.output ?? 0) + (options.tokenUsage.cacheRead ?? 0) + (options.tokenUsage.cacheWrite ?? 0),
|
|
46
34
|
cost: ZERO_USAGE.cost
|
|
@@ -53,7 +41,7 @@ function createAssistantMessage(params, text, options) {
|
|
|
53
41
|
}],
|
|
54
42
|
api: attribution.api ?? "openai-chatgpt-responses",
|
|
55
43
|
provider: attribution.provider,
|
|
56
|
-
model:
|
|
44
|
+
model: attribution.modelId,
|
|
57
45
|
usage,
|
|
58
46
|
stopReason: options.aborted ? "aborted" : options.promptError ? "error" : "stop",
|
|
59
47
|
errorMessage: options.promptError ? formatErrorMessage(options.promptError) : void 0,
|
|
@@ -98,4 +86,4 @@ function createAssistantMirrorMessage(params, title, text) {
|
|
|
98
86
|
};
|
|
99
87
|
}
|
|
100
88
|
//#endregion
|
|
101
|
-
export {
|
|
89
|
+
export { createAttributedCodexAssistantMessage as i, createAssistantMessage as n, createAssistantMirrorMessage as r, createAssistantCommentaryMessage as t };
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ut as isJsonObject } from "./shared-client-Dw-rzii0.js";
|
|
2
|
+
import { asSafeIntegerInRange, readStringField } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
3
|
+
import { normalizeUsage } from "openclaw/plugin-sdk/agent-harness-runtime";
|
|
2
4
|
import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
3
5
|
//#region extensions/codex/src/app-server/attempt-notifications.ts
|
|
4
6
|
/**
|
|
@@ -14,9 +16,9 @@ function describeNotificationActivity(notification) {
|
|
|
14
16
|
if (!item) return { lastNotificationMethod: notification.method };
|
|
15
17
|
return {
|
|
16
18
|
lastNotificationMethod: notification.method,
|
|
17
|
-
lastNotificationItemId:
|
|
18
|
-
lastNotificationItemType:
|
|
19
|
-
lastNotificationItemRole:
|
|
19
|
+
lastNotificationItemId: readStringField(item, "id"),
|
|
20
|
+
lastNotificationItemType: readStringField(item, "type"),
|
|
21
|
+
lastNotificationItemRole: readStringField(item, "role"),
|
|
20
22
|
lastAssistantTextPreview: readRawAssistantTextPreview(item)
|
|
21
23
|
};
|
|
22
24
|
}
|
|
@@ -59,25 +61,25 @@ function isCompletedAssistantNotification(notification) {
|
|
|
59
61
|
if (!isJsonObject(notification.params)) return false;
|
|
60
62
|
if (notification.method !== "item/completed") return false;
|
|
61
63
|
const item = isJsonObject(notification.params.item) ? notification.params.item : void 0;
|
|
62
|
-
return Boolean(item &&
|
|
64
|
+
return Boolean(item && readStringField(item, "type") === "agentMessage" && readStringField(item, "phase") !== "commentary");
|
|
63
65
|
}
|
|
64
66
|
/** Returns true for completed app-server reasoning items. */
|
|
65
67
|
function isReasoningItemCompletionNotification(notification) {
|
|
66
68
|
if (!isJsonObject(notification.params) || notification.method !== "item/completed") return false;
|
|
67
69
|
const item = isJsonObject(notification.params.item) ? notification.params.item : void 0;
|
|
68
|
-
return item ?
|
|
70
|
+
return item ? readStringField(item, "type") === "reasoning" : false;
|
|
69
71
|
}
|
|
70
72
|
/** Returns true for completed assistant commentary items. */
|
|
71
73
|
function isAssistantCommentaryCompletionNotification(notification) {
|
|
72
74
|
if (!isJsonObject(notification.params) || notification.method !== "item/completed") return false;
|
|
73
75
|
const item = isJsonObject(notification.params.item) ? notification.params.item : void 0;
|
|
74
|
-
return Boolean(item &&
|
|
76
|
+
return Boolean(item && readStringField(item, "type") === "agentMessage" && readStringField(item, "phase") === "commentary");
|
|
75
77
|
}
|
|
76
78
|
/** Returns true for completed raw response reasoning items. */
|
|
77
79
|
function isRawReasoningCompletionNotification(notification) {
|
|
78
80
|
if (!isJsonObject(notification.params) || notification.method !== "rawResponseItem/completed") return false;
|
|
79
81
|
const item = isJsonObject(notification.params.item) ? notification.params.item : void 0;
|
|
80
|
-
return item ?
|
|
82
|
+
return item ? readStringField(item, "type") === "reasoning" : false;
|
|
81
83
|
}
|
|
82
84
|
/** Returns true for streamed app-server reasoning progress. */
|
|
83
85
|
function isReasoningProgressNotification(notification) {
|
|
@@ -99,7 +101,7 @@ function shouldDisarmAssistantCompletionIdleWatch(notification) {
|
|
|
99
101
|
function readNotificationItemId(notification) {
|
|
100
102
|
if (!isJsonObject(notification.params)) return;
|
|
101
103
|
const item = isJsonObject(notification.params.item) ? notification.params.item : void 0;
|
|
102
|
-
return (item ?
|
|
104
|
+
return (item ? readStringField(item, "id") : void 0) ?? readStringField(notification.params, "itemId") ?? readStringField(notification.params, "id");
|
|
103
105
|
}
|
|
104
106
|
/** Detects completion for an OpenClaw dynamic tool result still awaited by Codex. */
|
|
105
107
|
function isPendingOpenClawDynamicToolCompletionNotification(notification, pendingOpenClawDynamicToolCompletionIds) {
|
|
@@ -107,14 +109,14 @@ function isPendingOpenClawDynamicToolCompletionNotification(notification, pendin
|
|
|
107
109
|
const itemId = readNotificationItemId(notification);
|
|
108
110
|
if (!itemId || !pendingOpenClawDynamicToolCompletionIds.has(itemId)) return false;
|
|
109
111
|
const item = isJsonObject(notification.params.item) ? notification.params.item : void 0;
|
|
110
|
-
const itemType = item ?
|
|
112
|
+
const itemType = item ? readStringField(item, "type") : void 0;
|
|
111
113
|
return itemType === void 0 || itemType === "dynamicToolCall";
|
|
112
114
|
}
|
|
113
115
|
/** Returns true for raw response tool-output completion notifications. */
|
|
114
116
|
function isRawToolOutputCompletionNotification(notification) {
|
|
115
117
|
if (notification.method !== "rawResponseItem/completed" || !isJsonObject(notification.params)) return false;
|
|
116
118
|
const item = isJsonObject(notification.params.item) ? notification.params.item : void 0;
|
|
117
|
-
switch (item ?
|
|
119
|
+
switch (item ? readStringField(item, "type") : void 0) {
|
|
118
120
|
case "custom_tool_call_output":
|
|
119
121
|
case "function_call_output": return true;
|
|
120
122
|
default: return false;
|
|
@@ -123,14 +125,14 @@ function isRawToolOutputCompletionNotification(notification) {
|
|
|
123
125
|
function isRawFunctionToolOutputCompletionNotification(notification) {
|
|
124
126
|
if (notification.method !== "rawResponseItem/completed" || !isJsonObject(notification.params)) return false;
|
|
125
127
|
const item = isJsonObject(notification.params.item) ? notification.params.item : void 0;
|
|
126
|
-
return item ?
|
|
128
|
+
return item ? readStringField(item, "type") === "function_call_output" : false;
|
|
127
129
|
}
|
|
128
130
|
/** Returns true for progress on Codex-native tool item types. */
|
|
129
131
|
function isNativeToolProgressNotification(notification) {
|
|
130
132
|
if (notification.method !== "item/started" && notification.method !== "item/completed" && notification.method !== "item/updated") return false;
|
|
131
133
|
if (!isJsonObject(notification.params)) return false;
|
|
132
134
|
const item = isJsonObject(notification.params.item) ? notification.params.item : void 0;
|
|
133
|
-
switch (item ?
|
|
135
|
+
switch (item ? readStringField(item, "type") : void 0) {
|
|
134
136
|
case "commandExecution":
|
|
135
137
|
case "fileChange":
|
|
136
138
|
case "mcpToolCall":
|
|
@@ -146,19 +148,19 @@ function isFileChangePatchUpdatedNotification(notification) {
|
|
|
146
148
|
function isRawAssistantProgressNotification(notification) {
|
|
147
149
|
if (notification.method !== "rawResponseItem/completed" || !isJsonObject(notification.params)) return false;
|
|
148
150
|
const item = isJsonObject(notification.params.item) ? notification.params.item : void 0;
|
|
149
|
-
return Boolean(item &&
|
|
151
|
+
return Boolean(item && readStringField(item, "type") === "message" && readStringField(item, "role") === "assistant" && readRawAssistantTextPreview(item));
|
|
150
152
|
}
|
|
151
153
|
/** Returns true for raw assistant completion outside commentary phase. */
|
|
152
154
|
function isRawAssistantCompletionNotification(notification) {
|
|
153
155
|
if (!isRawAssistantProgressNotification(notification) || !isJsonObject(notification.params)) return false;
|
|
154
156
|
const item = isJsonObject(notification.params.item) ? notification.params.item : void 0;
|
|
155
|
-
return Boolean(item &&
|
|
157
|
+
return Boolean(item && readStringField(item, "phase") !== "commentary");
|
|
156
158
|
}
|
|
157
159
|
function readRawAssistantTextPreview(item) {
|
|
158
|
-
if (
|
|
160
|
+
if (readStringField(item, "role") !== "assistant" || !Array.isArray(item.content)) return;
|
|
159
161
|
const text = item.content.flatMap((content) => {
|
|
160
162
|
if (!isJsonObject(content)) return [];
|
|
161
|
-
const contentText =
|
|
163
|
+
const contentText = readStringField(content, "text");
|
|
162
164
|
return contentText ? [contentText] : [];
|
|
163
165
|
}).join("\n").trim();
|
|
164
166
|
if (!text) return;
|
|
@@ -179,8 +181,8 @@ function isTerminalTurnStatus(status) {
|
|
|
179
181
|
function isCodexTurnAbortMarkerNotification(notification, options = {}) {
|
|
180
182
|
if (notification.method !== "rawResponseItem/completed" || !isJsonObject(notification.params)) return false;
|
|
181
183
|
const item = notification.params.item;
|
|
182
|
-
const role = isJsonObject(item) ?
|
|
183
|
-
if (!isJsonObject(item) ||
|
|
184
|
+
const role = isJsonObject(item) ? readStringField(item, "role") : void 0;
|
|
185
|
+
if (!isJsonObject(item) || readStringField(item, "type") !== "message" || role !== "user" && role !== "developer") return false;
|
|
184
186
|
const text = extractRawResponseItemText(item).trim();
|
|
185
187
|
const currentPromptTexts = [options.currentPromptText, ...options.currentPromptTexts ?? []].filter(isNonEmptyString).map((prompt) => prompt.trim());
|
|
186
188
|
if (role === "user" && currentPromptTexts.includes(text)) return false;
|
|
@@ -195,16 +197,12 @@ function extractRawResponseItemText(item) {
|
|
|
195
197
|
if (!Array.isArray(content)) return "";
|
|
196
198
|
return content.flatMap((entry) => {
|
|
197
199
|
if (!isJsonObject(entry)) return [];
|
|
198
|
-
const type =
|
|
200
|
+
const type = readStringField(entry, "type");
|
|
199
201
|
if (type !== "input_text" && type !== "text") return [];
|
|
200
|
-
const text =
|
|
202
|
+
const text = readStringField(entry, "text");
|
|
201
203
|
return text ? [text] : [];
|
|
202
204
|
}).join("");
|
|
203
205
|
}
|
|
204
|
-
function readString(record, key) {
|
|
205
|
-
const value = record[key];
|
|
206
|
-
return typeof value === "string" ? value : void 0;
|
|
207
|
-
}
|
|
208
206
|
/** Reads a typed Codex item from notification params when id/type are present. */
|
|
209
207
|
function readCodexNotificationItem(params) {
|
|
210
208
|
if (!isJsonObject(params) || !isJsonObject(params.item)) return;
|
|
@@ -216,13 +214,13 @@ function readRawResponseToolCallId(notification) {
|
|
|
216
214
|
if (notification.method !== "rawResponseItem/completed" || !isJsonObject(notification.params)) return;
|
|
217
215
|
const item = isJsonObject(notification.params.item) ? notification.params.item : void 0;
|
|
218
216
|
if (!item) return;
|
|
219
|
-
switch (
|
|
217
|
+
switch (readStringField(item, "type")) {
|
|
220
218
|
case "custom_tool_call":
|
|
221
219
|
case "function_call":
|
|
222
220
|
case "local_shell_call":
|
|
223
|
-
case "tool_search_call": return
|
|
221
|
+
case "tool_search_call": return readStringField(item, "call_id");
|
|
224
222
|
case "image_generation_call":
|
|
225
|
-
case "web_search_call": return
|
|
223
|
+
case "web_search_call": return readStringField(item, "id");
|
|
226
224
|
default: return;
|
|
227
225
|
}
|
|
228
226
|
}
|
|
@@ -241,4 +239,90 @@ function isNonEmptyString(value) {
|
|
|
241
239
|
return typeof value === "string" && value.length > 0;
|
|
242
240
|
}
|
|
243
241
|
//#endregion
|
|
244
|
-
|
|
242
|
+
//#region extensions/codex/src/app-server/event-projector-usage.ts
|
|
243
|
+
function readTokenCount(record, key) {
|
|
244
|
+
return asSafeIntegerInRange(record[key], { min: 0 });
|
|
245
|
+
}
|
|
246
|
+
function readCodexThreadTokenUsage(params) {
|
|
247
|
+
const tokenUsage = isJsonObject(params.tokenUsage) ? params.tokenUsage : void 0;
|
|
248
|
+
const last = tokenUsage && isJsonObject(tokenUsage.last) ? tokenUsage.last : void 0;
|
|
249
|
+
return last ? normalizeCodexThreadTokenUsage(last) : void 0;
|
|
250
|
+
}
|
|
251
|
+
function readCodexThreadContextSnapshot(params) {
|
|
252
|
+
const tokenUsage = isJsonObject(params.tokenUsage) ? params.tokenUsage : void 0;
|
|
253
|
+
const last = tokenUsage && isJsonObject(tokenUsage.last) ? tokenUsage.last : void 0;
|
|
254
|
+
const modelContextWindow = tokenUsage ? readTokenCount(tokenUsage, "modelContextWindow") : void 0;
|
|
255
|
+
const activeContextTokens = last ? readTokenCount(last, "totalTokens") : void 0;
|
|
256
|
+
const inputTokens = last ? readTokenCount(last, "inputTokens") : void 0;
|
|
257
|
+
const cachedInputTokens = last ? readTokenCount(last, "cachedInputTokens") : void 0;
|
|
258
|
+
const cacheWriteInputTokens = last ? readTokenCount(last, "cacheWriteInputTokens") : void 0;
|
|
259
|
+
const outputTokens = last ? readTokenCount(last, "outputTokens") : void 0;
|
|
260
|
+
const reasoningOutputTokens = last ? readTokenCount(last, "reasoningOutputTokens") : void 0;
|
|
261
|
+
return {
|
|
262
|
+
...activeContextTokens !== void 0 ? { activeContextTokens } : {},
|
|
263
|
+
...cachedInputTokens !== void 0 ? { cachedInputTokens } : {},
|
|
264
|
+
...cacheWriteInputTokens !== void 0 ? { cacheWriteInputTokens } : {},
|
|
265
|
+
...inputTokens !== void 0 ? { inputTokens } : {},
|
|
266
|
+
...modelContextWindow && modelContextWindow > 0 ? { modelContextWindow } : {},
|
|
267
|
+
...outputTokens !== void 0 ? { outputTokens } : {},
|
|
268
|
+
...inputTokens !== void 0 ? { promptTokens: inputTokens } : {},
|
|
269
|
+
...reasoningOutputTokens !== void 0 ? { reasoningOutputTokens } : {}
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
function projectCodexThreadUsageUpdate(params, currentUsage, applyUsage, emitContext) {
|
|
273
|
+
applyUsage(readCodexThreadTokenUsage(params) ?? currentUsage);
|
|
274
|
+
const context = readCodexThreadContextSnapshot(params);
|
|
275
|
+
if (Object.keys(context).length > 0) emitContext(context);
|
|
276
|
+
}
|
|
277
|
+
function normalizeCodexThreadTokenUsage(record) {
|
|
278
|
+
return normalizeCodexTokenUsageBreakdown(record);
|
|
279
|
+
}
|
|
280
|
+
function normalizeCodexResponseTokenUsage(record) {
|
|
281
|
+
return normalizeCodexTokenUsageBreakdown(record);
|
|
282
|
+
}
|
|
283
|
+
function normalizeCodexTokenUsageBreakdown(record) {
|
|
284
|
+
const totalTokens = readTokenCount(record, "totalTokens");
|
|
285
|
+
const inputTokens = readTokenCount(record, "inputTokens");
|
|
286
|
+
const cacheRead = readTokenCount(record, "cachedInputTokens");
|
|
287
|
+
const output = readTokenCount(record, "outputTokens");
|
|
288
|
+
const reasoningTokens = readTokenCount(record, "reasoningOutputTokens");
|
|
289
|
+
const cacheWrite = record.cacheWriteInputTokens === void 0 ? 0 : readTokenCount(record, "cacheWriteInputTokens");
|
|
290
|
+
const hasCoherentInput = inputTokens !== void 0 && cacheRead !== void 0 && cacheWrite !== void 0 && cacheRead + cacheWrite <= inputTokens;
|
|
291
|
+
const hasCoherentContext = hasCoherentInput && totalTokens !== void 0 && output !== void 0 && totalTokens === inputTokens + output;
|
|
292
|
+
const usage = normalizeUsage({
|
|
293
|
+
input: hasCoherentInput ? inputTokens - cacheRead - cacheWrite : void 0,
|
|
294
|
+
output,
|
|
295
|
+
cacheRead,
|
|
296
|
+
cacheWrite,
|
|
297
|
+
reasoningTokens,
|
|
298
|
+
total: totalTokens
|
|
299
|
+
});
|
|
300
|
+
if (!usage) return;
|
|
301
|
+
return {
|
|
302
|
+
...usage,
|
|
303
|
+
contextUsage: hasCoherentContext ? {
|
|
304
|
+
state: "available",
|
|
305
|
+
promptTokens: inputTokens,
|
|
306
|
+
totalTokens
|
|
307
|
+
} : { state: "unavailable" }
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
var CodexResponseCompletionProjection = class {
|
|
311
|
+
constructor() {
|
|
312
|
+
this.responseIds = /* @__PURE__ */ new Set();
|
|
313
|
+
}
|
|
314
|
+
get modelIterations() {
|
|
315
|
+
return this.responseIds.size;
|
|
316
|
+
}
|
|
317
|
+
clear() {
|
|
318
|
+
this.usage = void 0;
|
|
319
|
+
}
|
|
320
|
+
record(params) {
|
|
321
|
+
const responseId = readStringField(params, "responseId");
|
|
322
|
+
if (responseId) this.responseIds.add(responseId);
|
|
323
|
+
const usage = isJsonObject(params.usage) ? params.usage : void 0;
|
|
324
|
+
this.usage = usage ? normalizeCodexResponseTokenUsage(usage) : void 0;
|
|
325
|
+
}
|
|
326
|
+
};
|
|
327
|
+
//#endregion
|
|
328
|
+
export { readRawResponseToolCallId as C, updateActiveTurnItemIds as E, readNotificationItemId as S, updateActiveCompletionBlockerItemIds as T, isReasoningItemCompletionNotification as _, codexExecutionToolName as a, isTerminalTurnStatus as b, isAssistantCompletionReleaseNotification as c, isNativeToolProgressNotification as d, isPendingOpenClawDynamicToolCompletionNotification as f, isRawToolOutputCompletionNotification as g, isRawReasoningCompletionNotification as h, readCodexThreadContextSnapshot as i, isCodexTurnAbortMarkerNotification as l, isRawFunctionToolOutputCompletionNotification as m, normalizeCodexResponseTokenUsage as n, describeNotificationActivity as o, isRawAssistantProgressNotification as p, projectCodexThreadUsageUpdate as r, isAssistantCommentaryCompletionNotification as s, CodexResponseCompletionProjection as t, isFileChangePatchUpdatedNotification as u, isReasoningProgressNotification as v, shouldDisarmAssistantCompletionIdleWatch as w, readCodexNotificationItem as x, isRetryableErrorNotification as y };
|