@openclaw/codex 2026.9.1 → 2026.9.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 +18 -23
- package/dist/apply-B6el6hdO.js +357 -0
- package/dist/{attempt-client-cleanup-DYHcRQAa.js → attempt-client-cleanup-D6cR54TV.js} +113 -49
- package/dist/{attempt-context-DmQUNWwT.js → attempt-context-AO4DSjE0.js} +11 -9
- package/dist/{event-projector-usage-C5mcrGjp.js → attempt-notifications--H8zXR5-.js} +3 -89
- package/dist/auth-cache-key-Kq6oerr6.js +498 -0
- package/dist/auth-profile-CwzO4_RG.js +43 -0
- package/dist/auth-profile-selection-DFu9e167.js +45 -0
- package/dist/{binding-connection-E6uDsPlx.js → binding-connection-QqgcPCgk.js} +18 -3
- package/dist/{bounded-turn-wzJrwKKe.js → bounded-turn-lRpmZHFv.js} +54 -150
- package/dist/build-state-6RL6qohz.js +19 -0
- package/dist/{capabilities-dIjNVCYH.js → capabilities-BeqLPbtM.js} +2 -1
- package/dist/cli-metadata.js +1 -1
- package/dist/client-BEKu4yDx.js +3983 -0
- package/dist/command-dispatch-CisT9Jqq.js +21 -0
- package/dist/{command-formatters-CLHhEB1Q.js → command-formatters-DeTfrapr.js} +2 -2
- package/dist/{command-handlers-CTGb2csu.js → command-handlers-BfIsJEuA.js} +158 -76
- package/dist/command-rpc-BMqRQOFX.js +226 -0
- package/dist/{compact-_t0HQrUS.js → compact-CGJZ2rlb.js} +89 -49
- package/dist/config-JDfTI4VI.js +106 -0
- package/dist/{config-BhmfC1s6.js → config-options-jnIFvwxD.js} +208 -654
- package/dist/config-runtime-BWf6JLWG.js +11 -0
- package/dist/config-utils-C57JiJrU.js +69 -0
- package/dist/conversation-binding-CxOlHiix.js +889 -0
- package/dist/{plugin-marketplace-discovery-CfFlKqDl.js → conversation-control-CUCrSIQI.js} +36 -155
- package/dist/doctor-contract-api.js +8 -9
- package/dist/{dynamic-tools-BU9tmlYm.js → dynamic-tools-D-JBoaLt.js} +734 -698
- package/dist/{effective-mcp-catalog-DzYBW4h1.js → effective-mcp-catalog-J_5Ep5Um.js} +4 -3
- package/dist/{elicitation-input-DMkeki8d.js → elicitation-input-DPoK8F7w.js} +8 -22
- package/dist/ephemeral-turn-DSwzP8YY.js +101 -0
- package/dist/{event-projector-assistant-message-DHRFXKbS.js → event-projector-assistant-message-BmBM4qBV.js} +23 -27
- package/dist/event-projector-usage-CIyrYYid.js +102 -0
- package/dist/{harness-DXVZ5II5.js → harness-FR6eQgyO.js} +47 -17
- package/dist/harness.js +1 -1
- package/dist/history-rejection-B4nOXNXF.js +13 -0
- package/dist/{image-payload-sanitizer-CnfoUPCE.js → image-payload-sanitizer-tupAr-2o.js} +29 -15
- package/dist/incognito-session-uhrBF6wJ.js +15 -0
- package/dist/index.js +413 -2893
- package/dist/{isolated-completion-kg9kv4iH.js → isolated-completion-DHBefrzg.js} +12 -21
- package/dist/{managed-binary-4-Vjz5GH.js → managed-binary-DrjjRRUD.js} +17 -84
- package/dist/managed-thread-store-D1t5jh3G.js +66 -0
- package/dist/media-understanding-provider.js +4 -1
- package/dist/{model-catalog-CUM68Hkl.js → model-catalog-B_6M04Wo.js} +6 -5
- package/dist/{models-sYnEc0gd.js → models-P9k2qAof.js} +4 -4
- package/dist/native-execution-policy-umd0tgh4.js +128 -0
- package/dist/{native-subagent-monitor-CnH147jH.js → native-subagent-monitor-BbCUKRwC.js} +76 -48
- package/dist/node-cli-sessions-rj0ysJwM.js +527 -0
- package/dist/{node-exec-server.runtime-CstNHCmC.js → node-exec-server.runtime-BY_ctYnT.js} +54 -23
- package/dist/plan-BMJdMOEF.js +711 -0
- package/dist/plugin-activation-BQK-f5sV.js +133 -0
- package/dist/{thread-resume-C7pyVKeW.js → plugin-app-cache-key-CdSQzWyX.js} +5 -53
- package/dist/{plugin-approval-roundtrip-CNe-Xrjx.js → plugin-approval-roundtrip-DeW95wB5.js} +1 -1
- package/dist/plugin-inventory-CoRCzWW4.js +325 -0
- package/dist/plugin-marketplace-discovery-3akBizzF.js +134 -0
- package/dist/{plugin-metadata-cache-BFrPhb2c.js → plugin-metadata-cache-DgNfRAGA.js} +13 -9
- package/dist/protocol-CAAcVIKF.js +275 -0
- package/dist/{provider-capabilities-DW5p4k9w.js → provider-capabilities-W4tfK5Y5.js} +2 -2
- package/dist/{rate-limits-CawQJfUS.js → rate-limits-Bqnx1N4z.js} +1 -1
- package/dist/request-CGvGOpeR.js +198 -0
- package/dist/{run-attempt-D1hJO4fX.js → run-attempt-DwKds3DN.js} +1498 -1028
- package/dist/{runtime-artifact-C3jVimFn.js → runtime-artifact-T-NwqeSH.js} +28 -28
- package/dist/sandbox-guard-BcT66fWy.js +165 -0
- package/dist/{session-binding-BHuTCRZQ.js → session-binding-CKSepwIC.js} +118 -324
- package/dist/session-binding-record-CaZjYwNS.js +256 -0
- package/dist/session-catalog-HaDcp7Sv.js +1533 -0
- package/dist/session-catalog-adoption-BKLtSrwi.js +251 -0
- package/dist/session-catalog-archive-D0i2pGj2.js +56 -0
- package/dist/session-catalog-home-id-D7-aLiNt.js +190 -0
- package/dist/session-catalog-node-adoption-BUuDYY8R.js +182 -0
- package/dist/session-catalog-node-continue-CBtc4wkI.js +238 -0
- package/dist/session-catalog-parsing-CdD3JhdM.js +280 -0
- package/dist/session-catalog-provenance-DkJHo735.js +124 -0
- package/dist/{session-cli-CmFEXMAM.js → session-cli-CbgaHh0f.js} +3 -2
- package/dist/session-history-Cz-tOOYj.js +96 -0
- package/dist/{session-upstream-marker-C351-5Qw.js → session-history-import-DFN7sWRU.js} +5 -49
- package/dist/session-history-read-cxPUxyVV.js +50 -0
- package/dist/session-history-worker-runtime.js +60 -0
- package/dist/{settled-turn-context-D3SNWtUn.js → session-history.worker-CNEvGaU5.js} +75 -69
- package/dist/session-history.worker.js +2 -0
- package/dist/{session-initialization-BeWzjGiR.js → session-initialization-Jo86C60I.js} +2 -1
- package/dist/{session-permission-policy-DeWVTCMj.js → session-permission-policy-B22InTp_.js} +4 -7
- package/dist/{session-retirement-BujDjXVF.js → session-retirement-BSNG_mhf.js} +8 -7
- package/dist/session-upstream-marker-D15C9NHp.js +46 -0
- package/dist/settled-turn-context-Du6gdUDd.js +45 -0
- package/dist/{settled-turn-finalizer-BVJx4yoc.js → settled-turn-finalizer-BuLUrZl2.js} +54 -42
- package/dist/shared-client-CVhez2Uo.js +2911 -0
- package/dist/{side-question-BTZAII4l.js → side-question-DLbr2vUU.js} +135 -191
- package/dist/source-Da-h6f7e.js +518 -0
- package/dist/thread-archive-guard-D1bP04Tf.js +53 -0
- package/dist/{thread-lifecycle-DAcEJ_Om.js → thread-lifecycle-D1pzRwHB.js} +467 -977
- package/dist/{thread-ownership-zGokd8i1.js → thread-ownership-D6oASVRu.js} +15 -17
- package/dist/{thread-policy-g4KbJPzp.js → thread-policy-D8kI7yAO.js} +2 -2
- package/dist/thread-resume-T5cveyxA.js +52 -0
- package/dist/timeout-BVw8aaM1.js +33 -0
- package/dist/transcript-mirror-attestation-DibE0krH.js +89 -0
- package/dist/{transcript-mirror-DTUxFWa_.js → transcript-mirror-t5TOccct.js} +111 -379
- package/dist/{transport-stdio-CyPldczm.js → transport-stdio-BGjHoYLr.js} +80 -48
- package/dist/{upstream-session-fork-CYlBIGVt.js → upstream-session-fork-De-sLJ2r.js} +94 -166
- package/dist/{usage-Bj-rrzkR.js → usage-CPPTmBvZ.js} +4 -3
- package/dist/version-omm6IPI3.js +12 -0
- package/dist/{web-search-provider.runtime-D2FWSK4w.js → web-search-provider.runtime-CSVgQL0w.js} +3 -3
- package/openclaw.plugin.json +22 -1
- package/package.json +6 -6
- package/dist/request-DYAI5FQE.js +0 -475
- package/dist/session-catalog-yyvTWFOw.js +0 -3120
- package/dist/session-history-C5J1AKzG.js +0 -87
- package/dist/shared-client-DxcfF9KX.js +0 -7494
- package/dist/{auth-binding-Ds_QVm-X.js → auth-binding-Co2Vfcf_.js} +1 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { l as sessionBindingIdentity } from "./session-binding-record-CaZjYwNS.js";
|
|
2
|
+
import { _ as retainSharedCodexAppServerClientByInstanceId } from "./shared-client-CVhez2Uo.js";
|
|
3
|
+
import "./session-binding-CKSepwIC.js";
|
|
3
4
|
import { asOptionalRecord, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
4
5
|
import { assignMcpCatalogSafeServerNames } from "openclaw/plugin-sdk/agent-harness-runtime";
|
|
5
6
|
//#region extensions/codex/src/app-server/effective-mcp-catalog.ts
|
|
@@ -95,7 +96,7 @@ async function loadCodexEffectiveMcpCatalogFromThread(params) {
|
|
|
95
96
|
}
|
|
96
97
|
/** Loads MCP inventory from the bound Codex client while retaining its lease through all pages. */
|
|
97
98
|
async function loadCodexEffectiveMcpCatalog(params, options) {
|
|
98
|
-
const binding =
|
|
99
|
+
const binding = options.bindingStore.read(sessionBindingIdentity({
|
|
99
100
|
agentId: params.agentId,
|
|
100
101
|
sessionId: params.sessionId,
|
|
101
102
|
sessionKey: params.sessionKey,
|
|
@@ -1,17 +1,8 @@
|
|
|
1
1
|
import { agentHarnessStructuredInput } from "openclaw/plugin-sdk/agent-harness-runtime";
|
|
2
2
|
//#region extensions/codex/src/app-server/elicitation-input.ts
|
|
3
|
-
/**
|
|
3
|
+
/** Compiles a validated Codex input snapshot before it enters the per-turn queue. */
|
|
4
4
|
function compileCodexOrdinaryElicitation(params) {
|
|
5
|
-
|
|
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");
|
|
5
|
+
const requestTurnId = readValue(params.snapshot, "turnId");
|
|
15
6
|
if (typeof requestTurnId === "string" && requestTurnId !== params.turnId) return { kind: "ignored" };
|
|
16
7
|
if (requestTurnId !== null && typeof requestTurnId !== "string") return {
|
|
17
8
|
kind: "compiled",
|
|
@@ -20,13 +11,13 @@ function compileCodexOrdinaryElicitation(params) {
|
|
|
20
11
|
message: "OpenClaw declined an MCP elicitation with invalid turn correlation."
|
|
21
12
|
}
|
|
22
13
|
};
|
|
23
|
-
const mode = readCodexElicitationString(snapshot, "mode");
|
|
14
|
+
const mode = readCodexElicitationString(params.snapshot, "mode");
|
|
24
15
|
if (mode === "url") return {
|
|
25
16
|
kind: "compiled",
|
|
26
17
|
input: agentHarnessStructuredInput.compileUrl({
|
|
27
|
-
url: readValue(snapshot, "url"),
|
|
28
|
-
elicitationId: readValue(snapshot, "elicitationId"),
|
|
29
|
-
message: readValue(snapshot, "message"),
|
|
18
|
+
url: readValue(params.snapshot, "url"),
|
|
19
|
+
elicitationId: readValue(params.snapshot, "elicitationId"),
|
|
20
|
+
message: readValue(params.snapshot, "message"),
|
|
30
21
|
fallbackMessage: "Codex provided a URL",
|
|
31
22
|
protocolName: "MCP"
|
|
32
23
|
})
|
|
@@ -41,8 +32,8 @@ function compileCodexOrdinaryElicitation(params) {
|
|
|
41
32
|
return {
|
|
42
33
|
kind: "compiled",
|
|
43
34
|
input: agentHarnessStructuredInput.compileForm({
|
|
44
|
-
schema: readValue(snapshot, "requestedSchema"),
|
|
45
|
-
message: readCodexElicitationString(snapshot, "message"),
|
|
35
|
+
schema: readValue(params.snapshot, "requestedSchema"),
|
|
36
|
+
message: readCodexElicitationString(params.snapshot, "message"),
|
|
46
37
|
fallbackMessage: "Codex needs input",
|
|
47
38
|
options: {
|
|
48
39
|
protocolName: mode === "openai/form" ? "OpenAI" : "MCP",
|
|
@@ -62,10 +53,5 @@ function readCodexElicitationString(record, key) {
|
|
|
62
53
|
const value = readValue(record, key);
|
|
63
54
|
return typeof value === "string" ? value : void 0;
|
|
64
55
|
}
|
|
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
56
|
//#endregion
|
|
71
57
|
export { compileCodexOrdinaryElicitation };
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { o as isJsonObject } from "./protocol-CAAcVIKF.js";
|
|
2
|
+
import { T as readCodexTurnCompletedNotification } from "./client-BEKu4yDx.js";
|
|
3
|
+
import { p as getCodexAppServerTurnRouter } from "./attempt-client-cleanup-D6cR54TV.js";
|
|
4
|
+
import { o as isTerminalTurnStatus, s as readCodexNotificationItem } from "./attempt-notifications--H8zXR5-.js";
|
|
5
|
+
import { t as CodexUsageProjection } from "./event-projector-usage-CIyrYYid.js";
|
|
6
|
+
import { readStringField } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
7
|
+
import { toStringifiedError } from "openclaw/plugin-sdk/error-runtime";
|
|
8
|
+
import { createDeferred } from "openclaw/plugin-sdk/extension-shared";
|
|
9
|
+
//#region extensions/codex/src/app-server/ephemeral-turn.ts
|
|
10
|
+
/** One ephemeral turn; the client router owns correlation, buffering and request lifetime. */
|
|
11
|
+
var CodexEphemeralTurn = class {
|
|
12
|
+
constructor(client, threadId, options) {
|
|
13
|
+
this.options = options;
|
|
14
|
+
this.completion = createDeferred();
|
|
15
|
+
this.usage = new CodexUsageProjection();
|
|
16
|
+
this.items = /* @__PURE__ */ new Map();
|
|
17
|
+
this.assistantItems = /* @__PURE__ */ new Map();
|
|
18
|
+
this.assistantText = "";
|
|
19
|
+
this.route = getCodexAppServerTurnRouter(client).reserveThread({
|
|
20
|
+
threadId,
|
|
21
|
+
...options,
|
|
22
|
+
onNotification: async (notification, scope) => {
|
|
23
|
+
const params = isJsonObject(notification.params) ? notification.params : void 0;
|
|
24
|
+
if (params && scope.turnId) {
|
|
25
|
+
if (notification.method === "item/completed" && options.textMode === "all") {
|
|
26
|
+
const item = readCodexNotificationItem(params);
|
|
27
|
+
if (item) {
|
|
28
|
+
this.items.set(item.id, item);
|
|
29
|
+
if (item.type === "agentMessage" && item.text) this.assistantItems.set(item.id, item.text);
|
|
30
|
+
}
|
|
31
|
+
} else if (notification.method === "item/agentMessage/delta") {
|
|
32
|
+
const delta = readStringField(params, "delta") ?? "";
|
|
33
|
+
const itemId = readStringField(params, "itemId") ?? readStringField(params, "id") ?? "assistant";
|
|
34
|
+
const firstDelta = !this.assistantText && Boolean(delta);
|
|
35
|
+
this.assistantText += delta;
|
|
36
|
+
if (delta && options.textMode === "all") this.assistantItems.set(itemId, `${this.assistantItems.get(itemId) ?? ""}${delta}`);
|
|
37
|
+
if (firstDelta) await options.onAssistantMessageStart?.();
|
|
38
|
+
} else if (notification.method === "rawResponse/completed") this.usage.record(params);
|
|
39
|
+
else if (notification.method === "turn/completed") {
|
|
40
|
+
this.turn = readCodexTurnCompletedNotification(params)?.turn ?? this.turn;
|
|
41
|
+
this.completion.resolve();
|
|
42
|
+
} else if (notification.method === "error") {
|
|
43
|
+
this.usage.invalidateContext();
|
|
44
|
+
if (params.willRetry !== true) {
|
|
45
|
+
this.error = params;
|
|
46
|
+
this.completion.resolve();
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
await options.onNotification?.(notification, scope);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
this.route.armTurn();
|
|
54
|
+
}
|
|
55
|
+
get completed() {
|
|
56
|
+
return this.turn !== void 0;
|
|
57
|
+
}
|
|
58
|
+
async wait(turn, options) {
|
|
59
|
+
if (isTerminalTurnStatus(turn.status)) {
|
|
60
|
+
this.turn = turn;
|
|
61
|
+
this.completion.resolve();
|
|
62
|
+
}
|
|
63
|
+
const completion = this.route.bindTurn(turn.id, { completed: isTerminalTurnStatus(turn.status) }).then(() => this.completion.promise);
|
|
64
|
+
const signals = [this.route.signal, options.signal];
|
|
65
|
+
const abortError = () => options.signal.aborted ? options.abortError() : toStringifiedError(this.route.signal.reason);
|
|
66
|
+
let timer;
|
|
67
|
+
let abort = () => {};
|
|
68
|
+
try {
|
|
69
|
+
await Promise.race([completion, new Promise((_resolve, reject) => {
|
|
70
|
+
abort = () => {
|
|
71
|
+
if (options.signal.aborted || !this.route.completed) reject(abortError());
|
|
72
|
+
};
|
|
73
|
+
for (const signal of signals) {
|
|
74
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
75
|
+
if (signal.aborted) abort();
|
|
76
|
+
}
|
|
77
|
+
const timeout = options.timeout;
|
|
78
|
+
if (timeout) {
|
|
79
|
+
timer = setTimeout(() => reject(timeout.error), timeout.ms);
|
|
80
|
+
timer.unref?.();
|
|
81
|
+
}
|
|
82
|
+
})]);
|
|
83
|
+
} finally {
|
|
84
|
+
clearTimeout(timer);
|
|
85
|
+
for (const signal of signals) signal.removeEventListener("abort", abort);
|
|
86
|
+
}
|
|
87
|
+
const items = new Map(this.items);
|
|
88
|
+
for (const item of this.turn?.items ?? []) items.set(item.id, item);
|
|
89
|
+
const messages = (this.options.textMode === "last" ? this.turn?.items ?? [] : [...items.values()]).filter((item) => item.type === "agentMessage").map((item) => item.text.trim()).filter(Boolean);
|
|
90
|
+
const text = this.options.textMode === "last" ? messages.at(-1) || this.assistantText : messages.join("\n\n") || [...this.assistantItems.values()].map((message) => message.trim()).filter(Boolean).join("\n\n");
|
|
91
|
+
return {
|
|
92
|
+
turn: this.turn,
|
|
93
|
+
error: this.error,
|
|
94
|
+
items: [...items.values()],
|
|
95
|
+
text: text.trim(),
|
|
96
|
+
usage: this.usage.usage
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
//#endregion
|
|
101
|
+
export { CodexEphemeralTurn as t };
|
|
@@ -33,6 +33,7 @@ function createAttributedCodexAssistantMessage(attribution, text, options) {
|
|
|
33
33
|
totalTokens: options.tokenUsage.total ?? (options.tokenUsage.input ?? 0) + (options.tokenUsage.output ?? 0) + (options.tokenUsage.cacheRead ?? 0) + (options.tokenUsage.cacheWrite ?? 0),
|
|
34
34
|
cost: ZERO_USAGE.cost
|
|
35
35
|
} : ZERO_USAGE;
|
|
36
|
+
const refusal = options.providerRefusal;
|
|
36
37
|
return {
|
|
37
38
|
role: "assistant",
|
|
38
39
|
content: [{
|
|
@@ -43,25 +44,25 @@ function createAttributedCodexAssistantMessage(attribution, text, options) {
|
|
|
43
44
|
provider: attribution.provider,
|
|
44
45
|
model: attribution.modelId,
|
|
45
46
|
usage,
|
|
46
|
-
stopReason: options.aborted ? "aborted" : options.promptError ? "error" : "stop",
|
|
47
|
-
errorMessage: options.promptError ? formatErrorMessage(options.promptError) : void 0,
|
|
47
|
+
stopReason: options.aborted ? "aborted" : options.promptError || refusal ? "error" : "stop",
|
|
48
|
+
errorMessage: refusal?.message ?? (options.promptError ? formatErrorMessage(options.promptError) : void 0),
|
|
49
|
+
...refusal ? { diagnostics: [{
|
|
50
|
+
type: "provider_refusal",
|
|
51
|
+
timestamp: Date.now(),
|
|
52
|
+
details: {
|
|
53
|
+
provider: "openai",
|
|
54
|
+
category: refusal.category
|
|
55
|
+
}
|
|
56
|
+
}] } : {},
|
|
48
57
|
timestamp: Date.now()
|
|
49
58
|
};
|
|
50
59
|
}
|
|
51
60
|
function createAssistantCommentaryMessage(params, text, itemId, timestamp) {
|
|
52
|
-
const attribution = resolveCodexLocalRuntimeAttribution(params);
|
|
53
61
|
return {
|
|
54
|
-
|
|
55
|
-
content: [{
|
|
62
|
+
...createNonterminalAssistantMessage(params, [{
|
|
56
63
|
type: "text",
|
|
57
64
|
text
|
|
58
|
-
}],
|
|
59
|
-
api: attribution.api ?? "openai-chatgpt-responses",
|
|
60
|
-
provider: attribution.provider,
|
|
61
|
-
model: params.modelId,
|
|
62
|
-
usage: ZERO_USAGE,
|
|
63
|
-
stopReason: "stop",
|
|
64
|
-
timestamp,
|
|
65
|
+
}], timestamp),
|
|
65
66
|
openclawStreamFallback: {
|
|
66
67
|
replacementText: text,
|
|
67
68
|
source: "segment",
|
|
@@ -70,36 +71,31 @@ function createAssistantCommentaryMessage(params, text, itemId, timestamp) {
|
|
|
70
71
|
};
|
|
71
72
|
}
|
|
72
73
|
function createAssistantAsyncMessage(params, text, itemId, timestamp) {
|
|
73
|
-
const attribution = resolveCodexLocalRuntimeAttribution(params);
|
|
74
74
|
return {
|
|
75
|
-
|
|
76
|
-
content: [{
|
|
75
|
+
...createNonterminalAssistantMessage(params, [{
|
|
77
76
|
type: "text",
|
|
78
77
|
text
|
|
79
|
-
}],
|
|
80
|
-
api: attribution.api ?? "openai-chatgpt-responses",
|
|
81
|
-
provider: attribution.provider,
|
|
82
|
-
model: params.modelId,
|
|
83
|
-
usage: ZERO_USAGE,
|
|
84
|
-
stopReason: "stop",
|
|
85
|
-
timestamp,
|
|
78
|
+
}], timestamp),
|
|
86
79
|
openclawAsyncDelivery: { itemId }
|
|
87
80
|
};
|
|
88
81
|
}
|
|
89
82
|
function createAssistantReasoningMessage(params, text) {
|
|
83
|
+
return createNonterminalAssistantMessage(params, [{
|
|
84
|
+
type: "thinking",
|
|
85
|
+
thinking: text
|
|
86
|
+
}]);
|
|
87
|
+
}
|
|
88
|
+
function createNonterminalAssistantMessage(params, content, timestamp) {
|
|
90
89
|
const attribution = resolveCodexLocalRuntimeAttribution(params);
|
|
91
90
|
return {
|
|
92
91
|
role: "assistant",
|
|
93
|
-
content
|
|
94
|
-
type: "thinking",
|
|
95
|
-
thinking: text
|
|
96
|
-
}],
|
|
92
|
+
content,
|
|
97
93
|
api: attribution.api ?? "openai-chatgpt-responses",
|
|
98
94
|
provider: attribution.provider,
|
|
99
95
|
model: params.modelId,
|
|
100
96
|
usage: ZERO_USAGE,
|
|
101
97
|
stopReason: "stop",
|
|
102
|
-
timestamp: Date.now()
|
|
98
|
+
timestamp: timestamp ?? Date.now()
|
|
103
99
|
};
|
|
104
100
|
}
|
|
105
101
|
//#endregion
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { o as isJsonObject } from "./protocol-CAAcVIKF.js";
|
|
2
|
+
import { asSafeIntegerInRange, readStringField } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
3
|
+
import { normalizeUsage } from "openclaw/plugin-sdk/agent-harness-runtime";
|
|
4
|
+
//#region extensions/codex/src/app-server/event-projector-usage.ts
|
|
5
|
+
function readTokenCount(record, key) {
|
|
6
|
+
return asSafeIntegerInRange(record[key], { min: 0 });
|
|
7
|
+
}
|
|
8
|
+
function readCodexThreadTokenUsage(params) {
|
|
9
|
+
const tokenUsage = isJsonObject(params.tokenUsage) ? params.tokenUsage : void 0;
|
|
10
|
+
const last = tokenUsage && isJsonObject(tokenUsage.last) ? tokenUsage.last : void 0;
|
|
11
|
+
return last ? normalizeCodexResponseTokenUsage(last) : void 0;
|
|
12
|
+
}
|
|
13
|
+
function readCodexThreadContextSnapshot(params) {
|
|
14
|
+
const tokenUsage = isJsonObject(params.tokenUsage) ? params.tokenUsage : void 0;
|
|
15
|
+
const last = tokenUsage && isJsonObject(tokenUsage.last) ? tokenUsage.last : void 0;
|
|
16
|
+
const modelContextWindow = tokenUsage ? readTokenCount(tokenUsage, "modelContextWindow") : void 0;
|
|
17
|
+
const activeContextTokens = last ? readTokenCount(last, "totalTokens") : void 0;
|
|
18
|
+
const inputTokens = last ? readTokenCount(last, "inputTokens") : void 0;
|
|
19
|
+
const cachedInputTokens = last ? readTokenCount(last, "cachedInputTokens") : void 0;
|
|
20
|
+
const cacheWriteInputTokens = last ? readTokenCount(last, "cacheWriteInputTokens") : void 0;
|
|
21
|
+
const reasoningOutputTokens = last ? readTokenCount(last, "reasoningOutputTokens") : void 0;
|
|
22
|
+
return {
|
|
23
|
+
...activeContextTokens !== void 0 ? { activeContextTokens } : {},
|
|
24
|
+
...cachedInputTokens !== void 0 ? { cachedInputTokens } : {},
|
|
25
|
+
...cacheWriteInputTokens !== void 0 ? { cacheWriteInputTokens } : {},
|
|
26
|
+
...inputTokens !== void 0 ? { inputTokens } : {},
|
|
27
|
+
...modelContextWindow && modelContextWindow > 0 ? { modelContextWindow } : {},
|
|
28
|
+
...inputTokens !== void 0 ? { promptTokens: inputTokens } : {},
|
|
29
|
+
...reasoningOutputTokens !== void 0 ? { reasoningOutputTokens } : {}
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
function normalizeCodexResponseTokenUsage(record) {
|
|
33
|
+
const totalTokens = readTokenCount(record, "totalTokens");
|
|
34
|
+
const inputTokens = readTokenCount(record, "inputTokens");
|
|
35
|
+
const cacheRead = readTokenCount(record, "cachedInputTokens");
|
|
36
|
+
const output = readTokenCount(record, "outputTokens");
|
|
37
|
+
const reasoningTokens = readTokenCount(record, "reasoningOutputTokens");
|
|
38
|
+
const cacheWrite = record.cacheWriteInputTokens === void 0 ? 0 : readTokenCount(record, "cacheWriteInputTokens");
|
|
39
|
+
const hasCoherentInput = inputTokens !== void 0 && cacheRead !== void 0 && cacheWrite !== void 0 && cacheRead + cacheWrite <= inputTokens;
|
|
40
|
+
const hasCoherentContext = hasCoherentInput && totalTokens !== void 0 && output !== void 0 && totalTokens === inputTokens + output;
|
|
41
|
+
const usage = normalizeUsage({
|
|
42
|
+
input: hasCoherentInput ? inputTokens - cacheRead - cacheWrite : void 0,
|
|
43
|
+
output,
|
|
44
|
+
cacheRead,
|
|
45
|
+
cacheWrite,
|
|
46
|
+
reasoningTokens,
|
|
47
|
+
total: totalTokens
|
|
48
|
+
});
|
|
49
|
+
if (!usage) return;
|
|
50
|
+
return {
|
|
51
|
+
...usage,
|
|
52
|
+
contextUsage: hasCoherentContext ? {
|
|
53
|
+
state: "available",
|
|
54
|
+
promptTokens: inputTokens,
|
|
55
|
+
totalTokens
|
|
56
|
+
} : { state: "unavailable" }
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
var CodexUsageProjection = class {
|
|
60
|
+
constructor() {
|
|
61
|
+
this.responseIds = /* @__PURE__ */ new Set();
|
|
62
|
+
}
|
|
63
|
+
get usage() {
|
|
64
|
+
const usage = this.responseUsage ?? this.threadUsage;
|
|
65
|
+
return usage ? {
|
|
66
|
+
...usage,
|
|
67
|
+
contextUsage: this.contextUsage
|
|
68
|
+
} : void 0;
|
|
69
|
+
}
|
|
70
|
+
get modelIterations() {
|
|
71
|
+
return this.responseIds.size;
|
|
72
|
+
}
|
|
73
|
+
invalidateContext() {
|
|
74
|
+
this.contextUsage = { state: "unavailable" };
|
|
75
|
+
}
|
|
76
|
+
recordThread(params) {
|
|
77
|
+
const usage = readCodexThreadTokenUsage(params);
|
|
78
|
+
this.threadUsage = usage ?? this.threadUsage;
|
|
79
|
+
if (!this.responseUsage && usage) this.contextUsage = usage.contextUsage;
|
|
80
|
+
return readCodexThreadContextSnapshot(params);
|
|
81
|
+
}
|
|
82
|
+
record(params, reportOutputTokens) {
|
|
83
|
+
const responseId = readStringField(params, "responseId");
|
|
84
|
+
if (!responseId || this.responseIds.has(responseId)) return;
|
|
85
|
+
this.responseIds.add(responseId);
|
|
86
|
+
const usage = isJsonObject(params.usage) ? normalizeCodexResponseTokenUsage(params.usage) : void 0;
|
|
87
|
+
this.contextUsage = usage?.contextUsage ?? { state: "unavailable" };
|
|
88
|
+
this.responseUsage ??= {};
|
|
89
|
+
for (const field of [
|
|
90
|
+
"input",
|
|
91
|
+
"output",
|
|
92
|
+
"cacheRead",
|
|
93
|
+
"cacheWrite",
|
|
94
|
+
"reasoningTokens",
|
|
95
|
+
"total"
|
|
96
|
+
]) if (usage?.[field] !== void 0) this.responseUsage[field] = (this.responseUsage[field] ?? 0) + usage[field];
|
|
97
|
+
const outputTokens = usage?.output;
|
|
98
|
+
if (outputTokens !== void 0) reportOutputTokens?.(outputTokens);
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
//#endregion
|
|
102
|
+
export { readCodexThreadContextSnapshot as n, CodexUsageProjection as t };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { l as sessionBindingIdentity } from "./session-binding-record-CaZjYwNS.js";
|
|
2
|
+
import { t as codexBuildSymbol } from "./build-state-6RL6qohz.js";
|
|
1
3
|
import { resolvePluginConfigObject } from "openclaw/plugin-sdk/plugin-config-runtime";
|
|
2
|
-
import { runHostPreparedIsolatedCompletion } from "openclaw/plugin-sdk/simple-completion-runtime";
|
|
3
4
|
import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
4
5
|
//#region extensions/codex/src/app-server/model-runtime.ts
|
|
5
6
|
const CODEX_APP_SERVER_RUNTIME_MODEL_PARAM = "codexAppServerRuntimeModel";
|
|
@@ -12,7 +13,7 @@ function readCodexRuntimeModelId(model, fallbackId) {
|
|
|
12
13
|
//#endregion
|
|
13
14
|
//#region extensions/codex/harness.ts
|
|
14
15
|
const DEFAULT_CODEX_HARNESS_PROVIDER_IDS = /* @__PURE__ */ new Set(["codex", "openai"]);
|
|
15
|
-
const SHARED_CODEX_APP_SERVER_CLIENT_DISPOSER =
|
|
16
|
+
const SHARED_CODEX_APP_SERVER_CLIENT_DISPOSER = codexBuildSymbol("openclaw.codexAppServerClientDisposer");
|
|
16
17
|
const CODEX_TOOL_POLICY_SAFE_DENY_NAMES = [
|
|
17
18
|
"web_fetch",
|
|
18
19
|
"x_search",
|
|
@@ -74,10 +75,35 @@ function createCodexAppServerAgentHarness(options) {
|
|
|
74
75
|
conversationToolPolicySafeDenyTools: CODEX_TOOL_POLICY_SAFE_DENY_NAMES,
|
|
75
76
|
deliveryDefaults: { visibleReplies: "message_tool" },
|
|
76
77
|
authBootstrap: "harness",
|
|
78
|
+
resolveSessionRuntimeOwnership: (params) => {
|
|
79
|
+
const assertCurrent = () => {
|
|
80
|
+
params.assertCurrent();
|
|
81
|
+
if (disposed) throw new Error("Codex agent harness is disposed");
|
|
82
|
+
};
|
|
83
|
+
assertCurrent();
|
|
84
|
+
const identity = sessionBindingIdentity(params);
|
|
85
|
+
let binding = options.bindingStore.read(identity);
|
|
86
|
+
if (!binding) {
|
|
87
|
+
const previousSessionId = params.readPreviousSessionId?.();
|
|
88
|
+
binding = previousSessionId ? options.bindingStore.read({
|
|
89
|
+
...identity,
|
|
90
|
+
sessionId: previousSessionId
|
|
91
|
+
}) : void 0;
|
|
92
|
+
}
|
|
93
|
+
assertCurrent();
|
|
94
|
+
return binding?.preserveNativeModel === true ? {
|
|
95
|
+
model: "native",
|
|
96
|
+
auth: binding.connectionScope === "supervision" ? "native" : "host",
|
|
97
|
+
...binding.model?.trim() && binding.modelProvider ? { modelRef: {
|
|
98
|
+
provider: binding.modelProvider,
|
|
99
|
+
model: binding.model
|
|
100
|
+
} } : {}
|
|
101
|
+
} : void 0;
|
|
102
|
+
},
|
|
77
103
|
...sessionCatalogControlFactory && sessionRuntime ? { sessionFork: {
|
|
78
104
|
upstreamKinds: ["codex-app-server"],
|
|
79
105
|
fork: async (params) => {
|
|
80
|
-
const { forkCodexUpstreamSession } = await import("./upstream-session-fork-
|
|
106
|
+
const { forkCodexUpstreamSession } = await import("./upstream-session-fork-De-sLJ2r.js");
|
|
81
107
|
return await forkCodexUpstreamSession(params, {
|
|
82
108
|
bindingStore: options.bindingStore,
|
|
83
109
|
controlFactory: sessionCatalogControlFactory,
|
|
@@ -88,26 +114,26 @@ function createCodexAppServerAgentHarness(options) {
|
|
|
88
114
|
}
|
|
89
115
|
} } : {},
|
|
90
116
|
authBinding: { fingerprint: async (params) => {
|
|
91
|
-
const { fingerprintCodexAppServerAuthBinding } = await import("./auth-binding-
|
|
117
|
+
const { fingerprintCodexAppServerAuthBinding } = await import("./auth-binding-Co2Vfcf_.js").then((n) => n.t);
|
|
92
118
|
return fingerprintCodexAppServerAuthBinding(params);
|
|
93
119
|
} },
|
|
94
120
|
runtimeArtifact: { validate: async (binding) => {
|
|
95
|
-
const { validateCodexAppServerRuntimeArtifact } = await import("./runtime-artifact-
|
|
121
|
+
const { validateCodexAppServerRuntimeArtifact } = await import("./runtime-artifact-T-NwqeSH.js");
|
|
96
122
|
return validateCodexAppServerRuntimeArtifact(binding);
|
|
97
123
|
} },
|
|
98
124
|
fetchUsageSnapshot: async (ctx) => {
|
|
99
|
-
const { fetchCodexAppServerUsageSnapshot } = await import("./usage-
|
|
125
|
+
const { fetchCodexAppServerUsageSnapshot } = await import("./usage-CPPTmBvZ.js");
|
|
100
126
|
return await fetchCodexAppServerUsageSnapshot(ctx, { pluginConfig: options?.resolvePluginConfig?.() ?? options?.pluginConfig });
|
|
101
127
|
},
|
|
102
128
|
loadModelCatalog: async (params) => {
|
|
103
|
-
const { createCodexAppServerModelCatalog } = await import("./model-catalog-
|
|
129
|
+
const { createCodexAppServerModelCatalog } = await import("./model-catalog-B_6M04Wo.js");
|
|
104
130
|
if (disposed) return [];
|
|
105
131
|
modelCatalog ??= createCodexAppServerModelCatalog(harnessRuntimeId);
|
|
106
132
|
return await modelCatalog.load(params, resolveAttemptPluginConfig(params.config));
|
|
107
133
|
},
|
|
108
134
|
readModelCatalogReadiness: (params) => modelCatalog?.read(params, resolveAttemptPluginConfig(params.config)),
|
|
109
135
|
loadMcpToolCatalog: async (params) => {
|
|
110
|
-
const { loadCodexEffectiveMcpCatalog } = await import("./effective-mcp-catalog-
|
|
136
|
+
const { loadCodexEffectiveMcpCatalog } = await import("./effective-mcp-catalog-J_5Ep5Um.js");
|
|
111
137
|
return await loadCodexEffectiveMcpCatalog(params, { bindingStore: options.bindingStore });
|
|
112
138
|
},
|
|
113
139
|
supports: (ctx) => {
|
|
@@ -150,7 +176,7 @@ function createCodexAppServerAgentHarness(options) {
|
|
|
150
176
|
};
|
|
151
177
|
},
|
|
152
178
|
runAttempt: async (params) => {
|
|
153
|
-
const { runCodexAppServerAttempt } = await import("./run-attempt-
|
|
179
|
+
const { runCodexAppServerAttempt } = await import("./run-attempt-DwKds3DN.js");
|
|
154
180
|
return runCodexAppServerAttempt(params, {
|
|
155
181
|
bindingStore: options.bindingStore,
|
|
156
182
|
pluginConfig: resolveAttemptPluginConfig(params.config),
|
|
@@ -160,11 +186,15 @@ function createCodexAppServerAgentHarness(options) {
|
|
|
160
186
|
});
|
|
161
187
|
},
|
|
162
188
|
runIsolatedCompletionV2: async (params) => {
|
|
163
|
-
if (params.authorization.owner === "host")
|
|
164
|
-
|
|
189
|
+
if (params.authorization.owner === "host") {
|
|
190
|
+
const { runHostPreparedIsolatedCompletion } = await import("openclaw/plugin-sdk/simple-completion-runtime");
|
|
191
|
+
return runHostPreparedIsolatedCompletion(params);
|
|
192
|
+
}
|
|
193
|
+
const { runCodexIsolatedCompletion } = await import("./isolated-completion-DHBefrzg.js");
|
|
165
194
|
return runCodexIsolatedCompletion(params, { pluginConfig: options?.resolvePluginConfig?.() ?? options?.pluginConfig });
|
|
166
195
|
},
|
|
167
196
|
runIsolatedCompletion: async (params) => {
|
|
197
|
+
const { runHostPreparedIsolatedCompletion } = await import("openclaw/plugin-sdk/simple-completion-runtime");
|
|
168
198
|
return runHostPreparedIsolatedCompletion({
|
|
169
199
|
...params,
|
|
170
200
|
authorization: {
|
|
@@ -176,11 +206,11 @@ function createCodexAppServerAgentHarness(options) {
|
|
|
176
206
|
});
|
|
177
207
|
},
|
|
178
208
|
finalizeSettledTurn: async (params) => {
|
|
179
|
-
const { runCodexSettledTurnFinalization } = await import("./settled-turn-finalizer-
|
|
209
|
+
const { runCodexSettledTurnFinalization } = await import("./settled-turn-finalizer-BuLUrZl2.js");
|
|
180
210
|
return runCodexSettledTurnFinalization(params, { pluginConfig: options?.resolvePluginConfig?.() ?? options?.pluginConfig });
|
|
181
211
|
},
|
|
182
212
|
runSideQuestion: async (params) => {
|
|
183
|
-
const { runCodexAppServerSideQuestion } = await import("./side-question-
|
|
213
|
+
const { runCodexAppServerSideQuestion } = await import("./side-question-DLbr2vUU.js");
|
|
184
214
|
return runCodexAppServerSideQuestion(params, {
|
|
185
215
|
bindingStore: options.bindingStore,
|
|
186
216
|
pluginConfig: options?.resolvePluginConfig?.() ?? options?.pluginConfig,
|
|
@@ -190,20 +220,20 @@ function createCodexAppServerAgentHarness(options) {
|
|
|
190
220
|
});
|
|
191
221
|
},
|
|
192
222
|
compact: async (params) => {
|
|
193
|
-
const { maybeCompactCodexAppServerSession } = await import("./compact-
|
|
223
|
+
const { maybeCompactCodexAppServerSession } = await import("./compact-CGJZ2rlb.js");
|
|
194
224
|
return maybeCompactCodexAppServerSession(params, {
|
|
195
225
|
bindingStore: options.bindingStore,
|
|
196
226
|
pluginConfig: options?.resolvePluginConfig?.() ?? options?.pluginConfig
|
|
197
227
|
});
|
|
198
228
|
},
|
|
199
229
|
withSessionDeletion: async (params, run) => {
|
|
200
|
-
const { withCodexAppServerSessionDeletion } = await import("./session-retirement-
|
|
230
|
+
const { withCodexAppServerSessionDeletion } = await import("./session-retirement-BSNG_mhf.js");
|
|
201
231
|
params.assertCurrent();
|
|
202
232
|
return withCodexAppServerSessionDeletion(options.bindingStore, params, run);
|
|
203
233
|
},
|
|
204
234
|
reset: async (params) => {
|
|
205
235
|
if (params.sessionId && params.reason !== "deleted") {
|
|
206
|
-
const [{ reclaimCurrentCodexSessionGeneration
|
|
236
|
+
const [{ reclaimCurrentCodexSessionGeneration }, { retireCodexAppServerSessionGeneration }] = await Promise.all([import("./session-binding-CKSepwIC.js").then((n) => n.c), import("./session-retirement-BSNG_mhf.js")]);
|
|
207
237
|
const identity = sessionBindingIdentity({
|
|
208
238
|
agentId: params.agentId,
|
|
209
239
|
sessionId: params.sessionId,
|
|
@@ -235,7 +265,7 @@ function createCodexAppServerAgentHarness(options) {
|
|
|
235
265
|
/** Creates the private native-compaction bridge registered in host-owned capability state. */
|
|
236
266
|
function createCodexAppServerNativeCompaction(options) {
|
|
237
267
|
return async (params) => {
|
|
238
|
-
const { maybeCompactCodexAppServerSession } = await import("./compact-
|
|
268
|
+
const { maybeCompactCodexAppServerSession } = await import("./compact-CGJZ2rlb.js");
|
|
239
269
|
return maybeCompactCodexAppServerSession(params, {
|
|
240
270
|
bindingStore: options.bindingStore,
|
|
241
271
|
pluginConfig: options.resolvePluginConfig?.() ?? options.pluginConfig,
|
package/dist/harness.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as createCodexAppServerNativeCompaction, t as createCodexAppServerAgentHarness } from "./harness-
|
|
1
|
+
import { n as createCodexAppServerNativeCompaction, t as createCodexAppServerAgentHarness } from "./harness-FR6eQgyO.js";
|
|
2
2
|
export { createCodexAppServerAgentHarness, createCodexAppServerNativeCompaction };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
//#region extensions/codex/src/app-server/history-rejection.ts
|
|
2
|
+
/** Only an owning rejection site can supply a diagnostic; exception text is never evidence. */
|
|
3
|
+
var CodexHistoryRejection = class extends Error {
|
|
4
|
+
constructor(reason) {
|
|
5
|
+
super(`Codex history rejected: ${reason}`);
|
|
6
|
+
this.reason = reason;
|
|
7
|
+
}
|
|
8
|
+
};
|
|
9
|
+
function codexHistoryRejectionReason(error) {
|
|
10
|
+
return error instanceof CodexHistoryRejection ? error.reason : "history_read_failed";
|
|
11
|
+
}
|
|
12
|
+
//#endregion
|
|
13
|
+
export { codexHistoryRejectionReason as n, CodexHistoryRejection as t };
|
|
@@ -24,42 +24,56 @@ function sanitizeImageContentRecord(record, label) {
|
|
|
24
24
|
};
|
|
25
25
|
const commaIndex = imageUrl.indexOf(",");
|
|
26
26
|
const mime = imageUrl.slice(INLINE_IMAGE_DATA_URL_PREFIX.length, commaIndex).split(";")[0] ?? mimeType;
|
|
27
|
-
|
|
27
|
+
const data = imageUrl.slice(commaIndex + 1);
|
|
28
|
+
return mime === record.mimeType && data === record.data ? record : {
|
|
28
29
|
...record,
|
|
29
30
|
mimeType: mime,
|
|
30
|
-
data
|
|
31
|
+
data
|
|
31
32
|
};
|
|
32
33
|
}
|
|
33
34
|
if (record.type === "inputImage" && typeof record.imageUrl === "string") {
|
|
34
35
|
const imageUrl = sanitizeInlineImageDataUrl$1(record.imageUrl);
|
|
35
|
-
|
|
36
|
-
...record,
|
|
37
|
-
imageUrl
|
|
38
|
-
} : {
|
|
36
|
+
if (!imageUrl) return {
|
|
39
37
|
type: "inputText",
|
|
40
38
|
text: invalidInlineImageText(label)
|
|
41
39
|
};
|
|
40
|
+
return imageUrl === record.imageUrl ? record : {
|
|
41
|
+
...record,
|
|
42
|
+
imageUrl
|
|
43
|
+
};
|
|
42
44
|
}
|
|
43
45
|
if (record.type === "input_image" && typeof record.image_url === "string") {
|
|
44
46
|
const imageUrl = sanitizeInlineImageDataUrl$1(record.image_url);
|
|
45
|
-
|
|
46
|
-
...record,
|
|
47
|
-
image_url: imageUrl
|
|
48
|
-
} : {
|
|
47
|
+
if (!imageUrl) return {
|
|
49
48
|
type: "input_text",
|
|
50
49
|
text: invalidInlineImageText(label)
|
|
51
50
|
};
|
|
51
|
+
return imageUrl === record.image_url ? record : {
|
|
52
|
+
...record,
|
|
53
|
+
image_url: imageUrl
|
|
54
|
+
};
|
|
52
55
|
}
|
|
53
56
|
}
|
|
54
|
-
/**
|
|
57
|
+
/** Sanitizes images without copying unchanged history or mutating its owned snapshot. */
|
|
55
58
|
function sanitizeCodexHistoryImagePayloads(value, label) {
|
|
56
|
-
if (Array.isArray(value))
|
|
59
|
+
if (Array.isArray(value)) {
|
|
60
|
+
let next;
|
|
61
|
+
for (let index = 0; index < value.length; index++) {
|
|
62
|
+
const child = sanitizeCodexHistoryImagePayloads(value[index], label);
|
|
63
|
+
if (child !== value[index]) (next ??= value.slice())[index] = child;
|
|
64
|
+
}
|
|
65
|
+
return next ?? value;
|
|
66
|
+
}
|
|
57
67
|
if (!isRecord(value)) return value;
|
|
58
68
|
const imageRecord = sanitizeImageContentRecord(value, label);
|
|
59
69
|
if (imageRecord) return imageRecord;
|
|
60
|
-
|
|
61
|
-
for (const
|
|
62
|
-
|
|
70
|
+
let next;
|
|
71
|
+
for (const key in value) {
|
|
72
|
+
if (!Object.hasOwn(value, key)) continue;
|
|
73
|
+
const child = sanitizeCodexHistoryImagePayloads(value[key], label);
|
|
74
|
+
if (child !== value[key]) (next ??= { ...value })[key] = child;
|
|
75
|
+
}
|
|
76
|
+
return next ?? value;
|
|
63
77
|
}
|
|
64
78
|
//#endregion
|
|
65
79
|
export { sanitizeCodexHistoryImagePayloads as n, sanitizeInlineImageDataUrl$1 as r, invalidInlineImageText as t };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { resolveGlobalSingleton } from "openclaw/plugin-sdk/global-singleton";
|
|
2
|
+
import { KeyedAsyncQueue } from "openclaw/plugin-sdk/keyed-async-queue";
|
|
3
|
+
import { isIncognitoSessionKey as isIncognitoSessionKey$1 } from "openclaw/plugin-sdk/session-key-runtime";
|
|
4
|
+
//#region extensions/codex/src/app-server/thread-ownership-queue.ts
|
|
5
|
+
const nativeThreadOwners = resolveGlobalSingleton(Symbol.for("openclaw.codexNativeThreadOwners"), () => new KeyedAsyncQueue());
|
|
6
|
+
/** Serialize OpenClaw-owned lifecycle changes, not native-internal thread controllers. */
|
|
7
|
+
async function withCodexAppServerThreadMutation(threadId, run) {
|
|
8
|
+
return await nativeThreadOwners.enqueue(`thread:${threadId}`, run);
|
|
9
|
+
}
|
|
10
|
+
/** Serializes bound turns and retirement so detach cannot unsubscribe an active turn. */
|
|
11
|
+
async function withCodexConversationThreadActivity(bindingId, run) {
|
|
12
|
+
return await nativeThreadOwners.enqueue(`conversation:${bindingId}`, run);
|
|
13
|
+
}
|
|
14
|
+
//#endregion
|
|
15
|
+
export { withCodexAppServerThreadMutation as n, withCodexConversationThreadActivity as r, isIncognitoSessionKey$1 as t };
|