@openclaw/codex 2026.5.27-beta.1 → 2026.5.28-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{client-BVK_jmHW.js → client-TfDda-h3.js} +1 -1
- package/dist/{client-factory-fW4Hh9q_.js → client-factory-BPBvbguy.js} +2 -2
- package/dist/{command-handlers-YXjMla3v.js → command-handlers-B8MXR7fh.js} +11 -11
- package/dist/{compact-DIXx9K0Q.js → compact-Dyz0rQLl.js} +10 -8
- package/dist/{computer-use-CakwWGCR.js → computer-use-BRIifWhE.js} +2 -2
- package/dist/{config-0-UN67Qg.js → config-BW7NPdAQ.js} +10 -3
- package/dist/{conversation-binding-CWaG0k5A.js → conversation-binding-D8OO0S9R.js} +7 -7
- package/dist/harness.js +5 -5
- package/dist/index.js +13 -12
- package/dist/media-understanding-provider.js +6 -6
- package/dist/{models-_XwpqjR8.js → models-Dnasi6LR.js} +1 -1
- package/dist/{vision-tools-DqpLmF5H.js → native-hook-relay-DYOYE3qb.js} +691 -14
- package/dist/{notification-correlation-YINts3PA.js → notification-correlation-BVB6XFQM.js} +44 -3
- package/dist/provider.js +2 -2
- package/dist/{request-Dtg0vQrE.js → request-Cj95iOk6.js} +3 -3
- package/dist/{run-attempt-BIbGYJog.js → run-attempt-D9i99EqV.js} +8098 -7879
- package/dist/{session-binding-4fRldGaa.js → session-binding-DuJisBZB.js} +1 -1
- package/dist/{shared-client-8kIrP817.js → shared-client-DICbgRn5.js} +21 -3
- package/dist/{side-question-v4nixmAs.js → side-question-280VWjeH.js} +7 -8
- package/dist/{thread-lifecycle-DZAfY4d6.js → thread-lifecycle-1u5ogKG_.js} +4 -4
- package/npm-shrinkwrap.json +96 -1771
- package/package.json +4 -5
- package/dist/dynamic-tools-BSZIYzfP.js +0 -560
- package/dist/test-api.js +0 -51
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/codex",
|
|
3
|
-
"version": "2026.5.
|
|
3
|
+
"version": "2026.5.28-beta.1",
|
|
4
4
|
"description": "OpenClaw Codex app-server harness and model provider plugin with a Codex-managed GPT catalog.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -8,7 +8,6 @@
|
|
|
8
8
|
},
|
|
9
9
|
"type": "module",
|
|
10
10
|
"dependencies": {
|
|
11
|
-
"@earendil-works/pi-coding-agent": "0.75.5",
|
|
12
11
|
"@openai/codex": "0.134.0",
|
|
13
12
|
"typebox": "1.1.38",
|
|
14
13
|
"ws": "8.21.0",
|
|
@@ -27,10 +26,10 @@
|
|
|
27
26
|
"minHostVersion": ">=2026.5.1-beta.1"
|
|
28
27
|
},
|
|
29
28
|
"compat": {
|
|
30
|
-
"pluginApi": ">=2026.5.
|
|
29
|
+
"pluginApi": ">=2026.5.28-beta.1"
|
|
31
30
|
},
|
|
32
31
|
"build": {
|
|
33
|
-
"openclawVersion": "2026.5.
|
|
32
|
+
"openclawVersion": "2026.5.28-beta.1"
|
|
34
33
|
},
|
|
35
34
|
"release": {
|
|
36
35
|
"publishToClawHub": true,
|
|
@@ -47,7 +46,7 @@
|
|
|
47
46
|
"npm-shrinkwrap.json"
|
|
48
47
|
],
|
|
49
48
|
"peerDependencies": {
|
|
50
|
-
"openclaw": ">=2026.5.
|
|
49
|
+
"openclaw": ">=2026.5.28-beta.1"
|
|
51
50
|
},
|
|
52
51
|
"peerDependenciesMeta": {
|
|
53
52
|
"openclaw": {
|
|
@@ -1,560 +0,0 @@
|
|
|
1
|
-
import { E as sanitizeInlineImageDataUrl, w as invalidInlineImageText } from "./thread-lifecycle-DZAfY4d6.js";
|
|
2
|
-
import { asOptionalRecord, isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
3
|
-
import { HEARTBEAT_RESPONSE_TOOL_NAME, createAgentToolResultMiddlewareRunner, createCodexAppServerToolResultExtensionRunner, embeddedAgentLog, extractToolResultMediaArtifact, filterToolResultMediaUrls, isMessagingTool, isMessagingToolSendAction, isToolWrappedWithBeforeToolCallHook, normalizeHeartbeatToolResponse, projectRuntimeToolInputSchema, runAgentHarnessAfterToolCallHook, setBeforeToolCallDiagnosticsEnabled, wrapToolWithBeforeToolCallHook } from "openclaw/plugin-sdk/agent-harness-runtime";
|
|
4
|
-
import { emitTrustedDiagnosticEvent } from "openclaw/plugin-sdk/diagnostic-runtime";
|
|
5
|
-
import { normalizeAgentId } from "openclaw/plugin-sdk/routing";
|
|
6
|
-
//#region extensions/codex/src/app-server/dynamic-tool-profile.ts
|
|
7
|
-
const CODEX_APP_SERVER_OWNED_DYNAMIC_TOOL_EXCLUDES = [
|
|
8
|
-
"read",
|
|
9
|
-
"write",
|
|
10
|
-
"edit",
|
|
11
|
-
"apply_patch",
|
|
12
|
-
"exec",
|
|
13
|
-
"process",
|
|
14
|
-
"update_plan",
|
|
15
|
-
"tool_call",
|
|
16
|
-
"tool_describe",
|
|
17
|
-
"tool_search",
|
|
18
|
-
"tool_search_code"
|
|
19
|
-
];
|
|
20
|
-
const DYNAMIC_TOOL_NAME_ALIASES = {
|
|
21
|
-
bash: "exec",
|
|
22
|
-
"apply-patch": "apply_patch"
|
|
23
|
-
};
|
|
24
|
-
function normalizeCodexDynamicToolName(name) {
|
|
25
|
-
const normalized = name.trim().toLowerCase();
|
|
26
|
-
return DYNAMIC_TOOL_NAME_ALIASES[normalized] ?? normalized;
|
|
27
|
-
}
|
|
28
|
-
function isForcedPrivateQaCodexRuntime(env = process.env) {
|
|
29
|
-
return env.OPENCLAW_BUILD_PRIVATE_QA === "1" && env.OPENCLAW_QA_FORCE_RUNTIME?.trim().toLowerCase() === "codex";
|
|
30
|
-
}
|
|
31
|
-
function resolveCodexDynamicToolsLoading(config, env = process.env) {
|
|
32
|
-
return isForcedPrivateQaCodexRuntime(env) ? "direct" : config.codexDynamicToolsLoading ?? "searchable";
|
|
33
|
-
}
|
|
34
|
-
function filterCodexDynamicTools(tools, config, env = process.env) {
|
|
35
|
-
const excludes = /* @__PURE__ */ new Set();
|
|
36
|
-
if (!isForcedPrivateQaCodexRuntime(env)) for (const name of CODEX_APP_SERVER_OWNED_DYNAMIC_TOOL_EXCLUDES) excludes.add(name);
|
|
37
|
-
for (const name of config.codexDynamicToolsExclude ?? []) {
|
|
38
|
-
const trimmed = normalizeCodexDynamicToolName(name);
|
|
39
|
-
if (trimmed) excludes.add(trimmed);
|
|
40
|
-
}
|
|
41
|
-
return excludes.size === 0 ? tools : tools.filter((tool) => !excludes.has(normalizeCodexDynamicToolName(tool.name)));
|
|
42
|
-
}
|
|
43
|
-
//#endregion
|
|
44
|
-
//#region extensions/codex/src/app-server/dynamic-tools.ts
|
|
45
|
-
const CODEX_OPENCLAW_DYNAMIC_TOOL_NAMESPACE = "openclaw";
|
|
46
|
-
const ALWAYS_DIRECT_DYNAMIC_TOOL_NAMES = new Set(["sessions_yield"]);
|
|
47
|
-
const DEFAULT_CODEX_DYNAMIC_TOOL_RESULT_MAX_CHARS = 16e3;
|
|
48
|
-
function createCodexDynamicToolBridge(params) {
|
|
49
|
-
const toolResultHookContext = toToolResultHookContext(params.hookContext);
|
|
50
|
-
const toolResultMaxChars = resolveCodexDynamicToolResultMaxChars(params.hookContext);
|
|
51
|
-
const availableProjection = projectCodexDynamicTools(params.tools);
|
|
52
|
-
const registeredProjection = params.registeredTools ? projectCodexDynamicTools(params.registeredTools) : availableProjection;
|
|
53
|
-
const availableTools = availableProjection.tools.map(({ tool, inputSchema }) => {
|
|
54
|
-
if (isToolWrappedWithBeforeToolCallHook(tool)) {
|
|
55
|
-
setBeforeToolCallDiagnosticsEnabled(tool, false);
|
|
56
|
-
return {
|
|
57
|
-
tool,
|
|
58
|
-
inputSchema
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
return {
|
|
62
|
-
tool: wrapToolWithBeforeToolCallHook(tool, params.hookContext, { emitDiagnostics: false }),
|
|
63
|
-
inputSchema
|
|
64
|
-
};
|
|
65
|
-
});
|
|
66
|
-
const toolMap = new Map(availableTools.map(({ tool }) => [tool.name, tool]));
|
|
67
|
-
const registeredTools = registeredProjection.tools.map(({ tool }) => tool);
|
|
68
|
-
const registeredToolNames = new Set(registeredTools.map((tool) => tool.name));
|
|
69
|
-
const quarantinedTools = dedupeQuarantinedDynamicTools([...availableProjection.quarantinedTools, ...registeredProjection.quarantinedTools]);
|
|
70
|
-
warnQuarantinedDynamicTools(quarantinedTools);
|
|
71
|
-
emitQuarantinedDynamicToolDiagnostics(quarantinedTools, params.hookContext);
|
|
72
|
-
const telemetry = {
|
|
73
|
-
didSendViaMessagingTool: false,
|
|
74
|
-
messagingToolSentTexts: [],
|
|
75
|
-
messagingToolSentMediaUrls: [],
|
|
76
|
-
messagingToolSentTargets: [],
|
|
77
|
-
messagingToolSourceReplyPayloads: [],
|
|
78
|
-
toolMediaUrls: [],
|
|
79
|
-
toolAudioAsVoice: false,
|
|
80
|
-
quarantinedTools
|
|
81
|
-
};
|
|
82
|
-
const middlewareRunner = createAgentToolResultMiddlewareRunner({
|
|
83
|
-
runtime: "codex",
|
|
84
|
-
...toolResultHookContext
|
|
85
|
-
});
|
|
86
|
-
const legacyExtensionRunner = createCodexAppServerToolResultExtensionRunner(toolResultHookContext);
|
|
87
|
-
const directToolNames = new Set([...ALWAYS_DIRECT_DYNAMIC_TOOL_NAMES, ...params.directToolNames ?? []]);
|
|
88
|
-
return {
|
|
89
|
-
availableSpecs: availableTools.map(({ tool, inputSchema }) => createCodexDynamicToolSpec({
|
|
90
|
-
tool,
|
|
91
|
-
inputSchema,
|
|
92
|
-
loading: params.loading ?? "searchable",
|
|
93
|
-
directToolNames
|
|
94
|
-
})),
|
|
95
|
-
specs: registeredProjection.tools.map(({ tool, inputSchema }) => createCodexDynamicToolSpec({
|
|
96
|
-
tool,
|
|
97
|
-
inputSchema,
|
|
98
|
-
loading: params.loading ?? "searchable",
|
|
99
|
-
directToolNames
|
|
100
|
-
})),
|
|
101
|
-
telemetry,
|
|
102
|
-
handleToolCall: async (call, options) => {
|
|
103
|
-
const tool = toolMap.get(call.tool);
|
|
104
|
-
if (!tool) {
|
|
105
|
-
if (registeredToolNames.has(call.tool)) return {
|
|
106
|
-
contentItems: [{
|
|
107
|
-
type: "inputText",
|
|
108
|
-
text: `OpenClaw tool is not available for this turn: ${call.tool}`
|
|
109
|
-
}],
|
|
110
|
-
success: false
|
|
111
|
-
};
|
|
112
|
-
return {
|
|
113
|
-
contentItems: [{
|
|
114
|
-
type: "inputText",
|
|
115
|
-
text: `Unknown OpenClaw tool: ${call.tool}`
|
|
116
|
-
}],
|
|
117
|
-
success: false
|
|
118
|
-
};
|
|
119
|
-
}
|
|
120
|
-
const args = jsonObjectToRecord(call.arguments);
|
|
121
|
-
const startedAt = Date.now();
|
|
122
|
-
const signal = composeAbortSignals(params.signal, options?.signal);
|
|
123
|
-
let didStartExecution = false;
|
|
124
|
-
try {
|
|
125
|
-
const preparedArgs = tool.prepareArguments ? tool.prepareArguments(args) : args;
|
|
126
|
-
didStartExecution = true;
|
|
127
|
-
const rawResult = await tool.execute(call.callId, preparedArgs, signal);
|
|
128
|
-
const rawIsError = isToolResultError(rawResult);
|
|
129
|
-
const middlewareResult = await middlewareRunner.applyToolResultMiddleware({
|
|
130
|
-
threadId: call.threadId,
|
|
131
|
-
turnId: call.turnId,
|
|
132
|
-
toolCallId: call.callId,
|
|
133
|
-
toolName: tool.name,
|
|
134
|
-
args,
|
|
135
|
-
isError: rawIsError,
|
|
136
|
-
result: rawResult
|
|
137
|
-
});
|
|
138
|
-
const result = await legacyExtensionRunner.applyToolResultExtensions({
|
|
139
|
-
threadId: call.threadId,
|
|
140
|
-
turnId: call.turnId,
|
|
141
|
-
toolCallId: call.callId,
|
|
142
|
-
toolName: tool.name,
|
|
143
|
-
args,
|
|
144
|
-
result: middlewareResult
|
|
145
|
-
});
|
|
146
|
-
const resultIsError = rawIsError || isToolResultError(result);
|
|
147
|
-
collectToolTelemetry({
|
|
148
|
-
toolName: tool.name,
|
|
149
|
-
args,
|
|
150
|
-
result,
|
|
151
|
-
mediaTrustResult: rawResult,
|
|
152
|
-
telemetry,
|
|
153
|
-
isError: resultIsError
|
|
154
|
-
});
|
|
155
|
-
runAgentHarnessAfterToolCallHook({
|
|
156
|
-
toolName: tool.name,
|
|
157
|
-
toolCallId: call.callId,
|
|
158
|
-
runId: toolResultHookContext.runId,
|
|
159
|
-
agentId: toolResultHookContext.agentId,
|
|
160
|
-
sessionId: toolResultHookContext.sessionId,
|
|
161
|
-
sessionKey: toolResultHookContext.sessionKey,
|
|
162
|
-
channelId: toolResultHookContext.channelId,
|
|
163
|
-
startArgs: args,
|
|
164
|
-
result,
|
|
165
|
-
startedAt
|
|
166
|
-
});
|
|
167
|
-
const terminalType = inferToolResultDiagnosticTerminalType(result, resultIsError);
|
|
168
|
-
const response = withDiagnosticTerminalType({
|
|
169
|
-
contentItems: convertToolContents(result.content, toolResultMaxChars),
|
|
170
|
-
success: !resultIsError
|
|
171
|
-
}, terminalType);
|
|
172
|
-
withDynamicToolTermination(response, rawResult.terminate === true || result.terminate === true || isToolResultYield(rawResult) || isToolResultYield(result));
|
|
173
|
-
withDynamicToolAsyncStarted(response, isAsyncStartedToolResult(rawResult) || isAsyncStartedToolResult(result));
|
|
174
|
-
return withSideEffectEvidence(response, terminalType !== "blocked");
|
|
175
|
-
} catch (error) {
|
|
176
|
-
collectToolTelemetry({
|
|
177
|
-
toolName: tool.name,
|
|
178
|
-
args,
|
|
179
|
-
result: void 0,
|
|
180
|
-
telemetry,
|
|
181
|
-
isError: true
|
|
182
|
-
});
|
|
183
|
-
runAgentHarnessAfterToolCallHook({
|
|
184
|
-
toolName: tool.name,
|
|
185
|
-
toolCallId: call.callId,
|
|
186
|
-
runId: toolResultHookContext.runId,
|
|
187
|
-
agentId: toolResultHookContext.agentId,
|
|
188
|
-
sessionId: toolResultHookContext.sessionId,
|
|
189
|
-
sessionKey: toolResultHookContext.sessionKey,
|
|
190
|
-
channelId: toolResultHookContext.channelId,
|
|
191
|
-
startArgs: args,
|
|
192
|
-
error: error instanceof Error ? error.message : String(error),
|
|
193
|
-
startedAt
|
|
194
|
-
});
|
|
195
|
-
return withSideEffectEvidence(withDiagnosticTerminalType({
|
|
196
|
-
contentItems: [{
|
|
197
|
-
type: "inputText",
|
|
198
|
-
text: error instanceof Error ? error.message : String(error)
|
|
199
|
-
}],
|
|
200
|
-
success: false
|
|
201
|
-
}, "error"), didStartExecution);
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
};
|
|
205
|
-
}
|
|
206
|
-
function createCodexDynamicToolSpec(params) {
|
|
207
|
-
const base = {
|
|
208
|
-
name: params.tool.name,
|
|
209
|
-
description: params.tool.description,
|
|
210
|
-
inputSchema: params.inputSchema
|
|
211
|
-
};
|
|
212
|
-
if (params.loading === "direct" || params.directToolNames.has(params.tool.name)) return base;
|
|
213
|
-
return {
|
|
214
|
-
...base,
|
|
215
|
-
namespace: CODEX_OPENCLAW_DYNAMIC_TOOL_NAMESPACE,
|
|
216
|
-
deferLoading: true
|
|
217
|
-
};
|
|
218
|
-
}
|
|
219
|
-
function projectCodexDynamicTools(tools) {
|
|
220
|
-
const projectedTools = [];
|
|
221
|
-
const quarantinedTools = [];
|
|
222
|
-
for (const tool of tools) {
|
|
223
|
-
const projection = projectRuntimeToolInputSchema(tool.parameters, `${tool.name}.inputSchema`);
|
|
224
|
-
if (projection.violations.length > 0) {
|
|
225
|
-
quarantinedTools.push({
|
|
226
|
-
tool: tool.name,
|
|
227
|
-
violations: projection.violations
|
|
228
|
-
});
|
|
229
|
-
continue;
|
|
230
|
-
}
|
|
231
|
-
projectedTools.push({
|
|
232
|
-
tool,
|
|
233
|
-
inputSchema: projection.schema
|
|
234
|
-
});
|
|
235
|
-
}
|
|
236
|
-
return {
|
|
237
|
-
tools: projectedTools,
|
|
238
|
-
quarantinedTools
|
|
239
|
-
};
|
|
240
|
-
}
|
|
241
|
-
function warnQuarantinedDynamicTools(tools) {
|
|
242
|
-
if (tools.length === 0) return;
|
|
243
|
-
const unique = /* @__PURE__ */ new Map();
|
|
244
|
-
for (const tool of tools) unique.set(tool.tool, tool.violations);
|
|
245
|
-
embeddedAgentLog.warn(`codex app-server quarantined ${unique.size} dynamic ${unique.size === 1 ? "tool" : "tools"} with unsupported input schemas: ${[...unique.keys()].join(", ")}`, { tools: [...unique.entries()].map(([tool, violations]) => ({
|
|
246
|
-
tool,
|
|
247
|
-
violations
|
|
248
|
-
})) });
|
|
249
|
-
}
|
|
250
|
-
function emitQuarantinedDynamicToolDiagnostics(tools, ctx) {
|
|
251
|
-
for (const tool of tools) emitTrustedDiagnosticEvent({
|
|
252
|
-
type: "tool.execution.blocked",
|
|
253
|
-
runId: ctx?.runId,
|
|
254
|
-
sessionId: ctx?.sessionId,
|
|
255
|
-
sessionKey: ctx?.sessionKey,
|
|
256
|
-
toolName: tool.tool,
|
|
257
|
-
deniedReason: "unsupported_tool_schema",
|
|
258
|
-
reason: tool.violations.join(", ")
|
|
259
|
-
});
|
|
260
|
-
}
|
|
261
|
-
function dedupeQuarantinedDynamicTools(tools) {
|
|
262
|
-
return [...new Map(tools.map((tool) => [tool.tool, {
|
|
263
|
-
tool: tool.tool,
|
|
264
|
-
violations: tool.violations
|
|
265
|
-
}])).values()];
|
|
266
|
-
}
|
|
267
|
-
function toToolResultHookContext(ctx) {
|
|
268
|
-
const { agentId, sessionId, sessionKey, runId, channelId } = ctx ?? {};
|
|
269
|
-
return {
|
|
270
|
-
...agentId && { agentId },
|
|
271
|
-
...sessionId && { sessionId },
|
|
272
|
-
...sessionKey && { sessionKey },
|
|
273
|
-
...runId && { runId },
|
|
274
|
-
...channelId && { channelId }
|
|
275
|
-
};
|
|
276
|
-
}
|
|
277
|
-
function resolveCodexDynamicToolResultMaxChars(ctx) {
|
|
278
|
-
return resolveAgentContextLimitValue({
|
|
279
|
-
config: ctx?.config,
|
|
280
|
-
agentId: ctx?.agentId,
|
|
281
|
-
key: "toolResultMaxChars"
|
|
282
|
-
}) ?? DEFAULT_CODEX_DYNAMIC_TOOL_RESULT_MAX_CHARS;
|
|
283
|
-
}
|
|
284
|
-
function resolveAgentContextLimitValue(params) {
|
|
285
|
-
const agents = asOptionalRecord(params.config?.agents);
|
|
286
|
-
const defaultValue = readPositiveInteger(asOptionalRecord(asOptionalRecord(agents?.defaults)?.contextLimits)?.[params.key]);
|
|
287
|
-
if (!params.agentId) return defaultValue;
|
|
288
|
-
const list = agents?.list;
|
|
289
|
-
if (!Array.isArray(list)) return defaultValue;
|
|
290
|
-
const normalizedAgentId = normalizeAgentId(params.agentId);
|
|
291
|
-
return readPositiveInteger(asOptionalRecord(asOptionalRecord(list.find((entry) => {
|
|
292
|
-
const entryId = asOptionalRecord(entry)?.id;
|
|
293
|
-
return typeof entryId === "string" && normalizeAgentId(entryId) === normalizedAgentId;
|
|
294
|
-
}))?.contextLimits)?.[params.key]) ?? defaultValue;
|
|
295
|
-
}
|
|
296
|
-
function composeAbortSignals(...signals) {
|
|
297
|
-
const activeSignals = signals.filter((signal) => Boolean(signal));
|
|
298
|
-
if (activeSignals.length === 0) return new AbortController().signal;
|
|
299
|
-
if (activeSignals.length === 1) return activeSignals[0];
|
|
300
|
-
return AbortSignal.any(activeSignals);
|
|
301
|
-
}
|
|
302
|
-
function collectToolTelemetry(params) {
|
|
303
|
-
if (params.isError) return;
|
|
304
|
-
if (!params.isError && params.toolName === "cron" && isCronAddAction(params.args)) params.telemetry.successfulCronAdds = (params.telemetry.successfulCronAdds ?? 0) + 1;
|
|
305
|
-
if (!params.isError && params.toolName === HEARTBEAT_RESPONSE_TOOL_NAME) {
|
|
306
|
-
const response = normalizeHeartbeatToolResponse(params.result?.details);
|
|
307
|
-
if (response) params.telemetry.heartbeatToolResponse = response;
|
|
308
|
-
}
|
|
309
|
-
if (!params.isError && params.result) {
|
|
310
|
-
const media = extractToolResultMediaArtifact(params.result);
|
|
311
|
-
if (media) {
|
|
312
|
-
const mediaUrls = filterToolResultMediaUrls(params.toolName, media.mediaUrls, params.mediaTrustResult ?? params.result);
|
|
313
|
-
const seen = new Set(params.telemetry.toolMediaUrls);
|
|
314
|
-
for (const mediaUrl of mediaUrls) if (!seen.has(mediaUrl)) {
|
|
315
|
-
seen.add(mediaUrl);
|
|
316
|
-
params.telemetry.toolMediaUrls.push(mediaUrl);
|
|
317
|
-
}
|
|
318
|
-
if (media.audioAsVoice) params.telemetry.toolAudioAsVoice = true;
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
if (!isMessagingTool(params.toolName) || !isMessagingToolSendAction(params.toolName, params.args)) return;
|
|
322
|
-
params.telemetry.didSendViaMessagingTool = true;
|
|
323
|
-
const sourceReplyPayload = extractInternalSourceReplyPayload(params.result?.details);
|
|
324
|
-
if (sourceReplyPayload) {
|
|
325
|
-
params.telemetry.messagingToolSourceReplyPayloads.push(sourceReplyPayload);
|
|
326
|
-
return;
|
|
327
|
-
}
|
|
328
|
-
const text = readFirstString(params.args, [
|
|
329
|
-
"text",
|
|
330
|
-
"message",
|
|
331
|
-
"body",
|
|
332
|
-
"content"
|
|
333
|
-
]);
|
|
334
|
-
if (text) params.telemetry.messagingToolSentTexts.push(text);
|
|
335
|
-
const mediaUrls = collectMediaUrls(params.args);
|
|
336
|
-
params.telemetry.messagingToolSentMediaUrls.push(...mediaUrls);
|
|
337
|
-
params.telemetry.messagingToolSentTargets.push({
|
|
338
|
-
tool: params.toolName,
|
|
339
|
-
provider: readFirstString(params.args, ["provider", "channel"]) ?? params.toolName,
|
|
340
|
-
accountId: readFirstString(params.args, ["accountId", "account_id"]),
|
|
341
|
-
to: readFirstString(params.args, [
|
|
342
|
-
"to",
|
|
343
|
-
"target",
|
|
344
|
-
"recipient"
|
|
345
|
-
]),
|
|
346
|
-
threadId: readFirstString(params.args, [
|
|
347
|
-
"threadId",
|
|
348
|
-
"thread_id",
|
|
349
|
-
"messageThreadId"
|
|
350
|
-
]),
|
|
351
|
-
...text ? { text } : {},
|
|
352
|
-
...mediaUrls.length > 0 ? { mediaUrls } : {}
|
|
353
|
-
});
|
|
354
|
-
}
|
|
355
|
-
function extractInternalSourceReplyPayload(details) {
|
|
356
|
-
if (!isRecord(details) || details.sourceReplySink !== "internal-ui") return;
|
|
357
|
-
const rawPayload = details.sourceReply;
|
|
358
|
-
if (!isRecord(rawPayload)) return;
|
|
359
|
-
const text = readFirstString(rawPayload, ["text", "message"]);
|
|
360
|
-
const mediaUrls = collectMediaUrls(rawPayload);
|
|
361
|
-
const mediaUrl = typeof rawPayload.mediaUrl === "string" && rawPayload.mediaUrl.trim() ? rawPayload.mediaUrl.trim() : mediaUrls[0];
|
|
362
|
-
const payload = {
|
|
363
|
-
...text ? { text } : {},
|
|
364
|
-
...mediaUrl ? { mediaUrl } : {},
|
|
365
|
-
...mediaUrls.length > 0 ? { mediaUrls } : {},
|
|
366
|
-
...rawPayload.audioAsVoice === true ? { audioAsVoice: true } : {},
|
|
367
|
-
...isRecord(rawPayload.presentation) ? { presentation: rawPayload.presentation } : {},
|
|
368
|
-
...isRecord(rawPayload.interactive) ? { interactive: rawPayload.interactive } : {},
|
|
369
|
-
...isRecord(rawPayload.channelData) ? { channelData: rawPayload.channelData } : {},
|
|
370
|
-
...typeof details.idempotencyKey === "string" && details.idempotencyKey.trim() ? { idempotencyKey: details.idempotencyKey.trim() } : {}
|
|
371
|
-
};
|
|
372
|
-
return text || mediaUrls.length > 0 || payload.presentation || payload.interactive ? payload : void 0;
|
|
373
|
-
}
|
|
374
|
-
function readPositiveInteger(value) {
|
|
375
|
-
if (typeof value !== "number" || !Number.isFinite(value) || value <= 0) return;
|
|
376
|
-
return Math.floor(value);
|
|
377
|
-
}
|
|
378
|
-
function isToolResultError(result) {
|
|
379
|
-
const details = result.details;
|
|
380
|
-
if (!isRecord(details)) return false;
|
|
381
|
-
if (details.timedOut === true) return true;
|
|
382
|
-
if (typeof details.exitCode === "number" && details.exitCode !== 0) return true;
|
|
383
|
-
if (typeof details.status !== "string") return false;
|
|
384
|
-
const status = details.status.trim().toLowerCase();
|
|
385
|
-
return status !== "" && status !== "0" && status !== "ok" && status !== "success" && status !== "completed" && status !== "recorded" && status !== "pending" && status !== "started" && status !== "running" && status !== "yielded";
|
|
386
|
-
}
|
|
387
|
-
function isToolResultYield(result) {
|
|
388
|
-
const details = result.details;
|
|
389
|
-
if (!isRecord(details) || typeof details.status !== "string") return false;
|
|
390
|
-
return details.status.trim().toLowerCase() === "yielded";
|
|
391
|
-
}
|
|
392
|
-
function isAsyncStartedToolResult(result) {
|
|
393
|
-
const details = result.details;
|
|
394
|
-
return isRecord(details) && details.async === true && details.status === "started";
|
|
395
|
-
}
|
|
396
|
-
function inferToolResultDiagnosticTerminalType(result, isError) {
|
|
397
|
-
const details = result.details;
|
|
398
|
-
if (isRecord(details) && typeof details.status === "string") {
|
|
399
|
-
if (details.status.trim().toLowerCase() === "blocked") return "blocked";
|
|
400
|
-
}
|
|
401
|
-
return isError ? "error" : "completed";
|
|
402
|
-
}
|
|
403
|
-
function withDiagnosticTerminalType(response, terminalType) {
|
|
404
|
-
Object.defineProperty(response, "diagnosticTerminalType", {
|
|
405
|
-
configurable: true,
|
|
406
|
-
enumerable: false,
|
|
407
|
-
value: terminalType
|
|
408
|
-
});
|
|
409
|
-
return response;
|
|
410
|
-
}
|
|
411
|
-
function withSideEffectEvidence(response, sideEffectEvidence) {
|
|
412
|
-
if (!sideEffectEvidence) return response;
|
|
413
|
-
Object.defineProperty(response, "sideEffectEvidence", {
|
|
414
|
-
configurable: true,
|
|
415
|
-
enumerable: false,
|
|
416
|
-
value: true
|
|
417
|
-
});
|
|
418
|
-
return response;
|
|
419
|
-
}
|
|
420
|
-
function withDynamicToolTermination(response, terminate) {
|
|
421
|
-
if (!terminate) return response;
|
|
422
|
-
Object.defineProperty(response, "terminate", {
|
|
423
|
-
configurable: true,
|
|
424
|
-
enumerable: false,
|
|
425
|
-
value: true
|
|
426
|
-
});
|
|
427
|
-
return response;
|
|
428
|
-
}
|
|
429
|
-
function withDynamicToolAsyncStarted(response, asyncStarted) {
|
|
430
|
-
if (!asyncStarted) return response;
|
|
431
|
-
Object.defineProperty(response, "asyncStarted", {
|
|
432
|
-
configurable: true,
|
|
433
|
-
enumerable: false,
|
|
434
|
-
value: true
|
|
435
|
-
});
|
|
436
|
-
return response;
|
|
437
|
-
}
|
|
438
|
-
function normalizeToolResultMaxChars(maxChars) {
|
|
439
|
-
return typeof maxChars === "number" && Number.isFinite(maxChars) && maxChars > 0 ? Math.floor(maxChars) : DEFAULT_CODEX_DYNAMIC_TOOL_RESULT_MAX_CHARS;
|
|
440
|
-
}
|
|
441
|
-
function convertToolContents(content, toolResultMaxChars = DEFAULT_CODEX_DYNAMIC_TOOL_RESULT_MAX_CHARS) {
|
|
442
|
-
const maxChars = normalizeToolResultMaxChars(toolResultMaxChars);
|
|
443
|
-
const totalTextChars = content.reduce((total, item) => total + (item.type === "text" ? item.text.length : 0), 0);
|
|
444
|
-
if (totalTextChars <= maxChars) return content.flatMap(convertToolContent);
|
|
445
|
-
const noticeText = `...(OpenClaw truncated dynamic tool result: original ${totalTextChars} chars, showing ${maxChars}; rerun with narrower args.)`;
|
|
446
|
-
const notice = `\n${noticeText}`;
|
|
447
|
-
let remainingTextBudget = Math.max(0, maxChars - notice.length);
|
|
448
|
-
let appendedNotice = false;
|
|
449
|
-
const output = [];
|
|
450
|
-
for (const item of content) {
|
|
451
|
-
if (item.type !== "text") {
|
|
452
|
-
output.push(...convertToolContent(item));
|
|
453
|
-
continue;
|
|
454
|
-
}
|
|
455
|
-
if (appendedNotice) continue;
|
|
456
|
-
if (notice.length >= maxChars) {
|
|
457
|
-
output.push({
|
|
458
|
-
type: "inputText",
|
|
459
|
-
text: noticeText.slice(0, maxChars)
|
|
460
|
-
});
|
|
461
|
-
appendedNotice = true;
|
|
462
|
-
continue;
|
|
463
|
-
}
|
|
464
|
-
const sliceLength = Math.min(item.text.length, remainingTextBudget);
|
|
465
|
-
remainingTextBudget -= sliceLength;
|
|
466
|
-
const shouldAppendNotice = remainingTextBudget <= 0;
|
|
467
|
-
const text = item.text.slice(0, sliceLength);
|
|
468
|
-
if (shouldAppendNotice) {
|
|
469
|
-
output.push({
|
|
470
|
-
type: "inputText",
|
|
471
|
-
text: `${text.trimEnd()}${notice}`.slice(0, maxChars)
|
|
472
|
-
});
|
|
473
|
-
appendedNotice = true;
|
|
474
|
-
} else if (text.length > 0) output.push({
|
|
475
|
-
type: "inputText",
|
|
476
|
-
text
|
|
477
|
-
});
|
|
478
|
-
}
|
|
479
|
-
if (!appendedNotice) output.push({
|
|
480
|
-
type: "inputText",
|
|
481
|
-
text: noticeText.slice(0, maxChars)
|
|
482
|
-
});
|
|
483
|
-
return output;
|
|
484
|
-
}
|
|
485
|
-
function convertToolContent(content) {
|
|
486
|
-
if (content.type === "text") return [{
|
|
487
|
-
type: "inputText",
|
|
488
|
-
text: content.text
|
|
489
|
-
}];
|
|
490
|
-
const imageUrl = sanitizeInlineImageDataUrl(`data:${content.mimeType};base64,${content.data}`);
|
|
491
|
-
if (!imageUrl) return [{
|
|
492
|
-
type: "inputText",
|
|
493
|
-
text: invalidInlineImageText("codex dynamic tool")
|
|
494
|
-
}];
|
|
495
|
-
return [{
|
|
496
|
-
type: "inputImage",
|
|
497
|
-
imageUrl
|
|
498
|
-
}];
|
|
499
|
-
}
|
|
500
|
-
function jsonObjectToRecord(value) {
|
|
501
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) return {};
|
|
502
|
-
return value;
|
|
503
|
-
}
|
|
504
|
-
function readFirstString(record, keys) {
|
|
505
|
-
for (const key of keys) {
|
|
506
|
-
const value = record[key];
|
|
507
|
-
if (typeof value === "string" && value.trim()) return value.trim();
|
|
508
|
-
if (typeof value === "number" && Number.isFinite(value)) return String(value);
|
|
509
|
-
}
|
|
510
|
-
}
|
|
511
|
-
function collectMediaUrls(record) {
|
|
512
|
-
const urls = [];
|
|
513
|
-
const pushMediaUrl = (value) => {
|
|
514
|
-
if (typeof value === "string" && value.trim()) urls.push(value.trim());
|
|
515
|
-
};
|
|
516
|
-
const pushAttachment = (value) => {
|
|
517
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) return;
|
|
518
|
-
const attachment = value;
|
|
519
|
-
for (const key of [
|
|
520
|
-
"media",
|
|
521
|
-
"mediaUrl",
|
|
522
|
-
"path",
|
|
523
|
-
"filePath",
|
|
524
|
-
"fileUrl",
|
|
525
|
-
"url"
|
|
526
|
-
]) pushMediaUrl(attachment[key]);
|
|
527
|
-
};
|
|
528
|
-
for (const key of [
|
|
529
|
-
"media",
|
|
530
|
-
"mediaUrl",
|
|
531
|
-
"media_url",
|
|
532
|
-
"path",
|
|
533
|
-
"filePath",
|
|
534
|
-
"fileUrl",
|
|
535
|
-
"imageUrl",
|
|
536
|
-
"image_url"
|
|
537
|
-
]) {
|
|
538
|
-
const value = record[key];
|
|
539
|
-
pushMediaUrl(value);
|
|
540
|
-
}
|
|
541
|
-
for (const key of [
|
|
542
|
-
"mediaUrls",
|
|
543
|
-
"media_urls",
|
|
544
|
-
"imageUrls",
|
|
545
|
-
"image_urls"
|
|
546
|
-
]) {
|
|
547
|
-
const value = record[key];
|
|
548
|
-
if (!Array.isArray(value)) continue;
|
|
549
|
-
for (const entry of value) pushMediaUrl(entry);
|
|
550
|
-
}
|
|
551
|
-
const attachments = record.attachments;
|
|
552
|
-
if (Array.isArray(attachments)) for (const attachment of attachments) pushAttachment(attachment);
|
|
553
|
-
return urls;
|
|
554
|
-
}
|
|
555
|
-
function isCronAddAction(args) {
|
|
556
|
-
const action = args.action;
|
|
557
|
-
return typeof action === "string" && action.trim().toLowerCase() === "add";
|
|
558
|
-
}
|
|
559
|
-
//#endregion
|
|
560
|
-
export { resolveCodexDynamicToolsLoading as a, normalizeCodexDynamicToolName as i, filterCodexDynamicTools as n, isForcedPrivateQaCodexRuntime as r, createCodexDynamicToolBridge as t };
|
package/dist/test-api.js
DELETED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { l as resolveCodexAppServerRuntimeOptions } from "./config-0-UN67Qg.js";
|
|
2
|
-
import { a as buildDeveloperInstructions, l as buildTurnStartParams, o as buildThreadResumeParams, s as buildThreadStartParams } from "./thread-lifecycle-DZAfY4d6.js";
|
|
3
|
-
import { n as filterCodexDynamicTools, t as createCodexDynamicToolBridge } from "./dynamic-tools-BSZIYzfP.js";
|
|
4
|
-
//#region extensions/codex/test-api.ts
|
|
5
|
-
function resolveCodexPromptSnapshotAppServerOptions(pluginConfig) {
|
|
6
|
-
return resolveCodexAppServerRuntimeOptions({
|
|
7
|
-
pluginConfig,
|
|
8
|
-
env: {},
|
|
9
|
-
requirementsToml: null
|
|
10
|
-
});
|
|
11
|
-
}
|
|
12
|
-
function buildCodexHarnessPromptSnapshot(params) {
|
|
13
|
-
const developerInstructions = joinPresentSections(buildDeveloperInstructions(params.attempt, { dynamicTools: params.dynamicTools }), params.developerInstructionAdditions);
|
|
14
|
-
return {
|
|
15
|
-
developerInstructions,
|
|
16
|
-
threadStartParams: buildThreadStartParams(params.attempt, {
|
|
17
|
-
cwd: params.cwd,
|
|
18
|
-
dynamicTools: params.dynamicTools,
|
|
19
|
-
appServer: params.appServer,
|
|
20
|
-
developerInstructions,
|
|
21
|
-
config: params.config
|
|
22
|
-
}),
|
|
23
|
-
threadResumeParams: buildThreadResumeParams(params.attempt, {
|
|
24
|
-
threadId: params.threadId,
|
|
25
|
-
appServer: params.appServer,
|
|
26
|
-
developerInstructions,
|
|
27
|
-
config: params.config
|
|
28
|
-
}),
|
|
29
|
-
turnStartParams: buildTurnStartParams(params.attempt, {
|
|
30
|
-
threadId: params.threadId,
|
|
31
|
-
cwd: params.cwd,
|
|
32
|
-
appServer: params.appServer,
|
|
33
|
-
promptText: params.promptText,
|
|
34
|
-
turnScopedDeveloperInstructions: params.turnScopedDeveloperInstructions,
|
|
35
|
-
heartbeatCollaborationInstructions: params.heartbeatCollaborationInstructions
|
|
36
|
-
})
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
|
-
function joinPresentSections(...sections) {
|
|
40
|
-
return sections.filter((section) => Boolean(section?.trim())).join("\n\n");
|
|
41
|
-
}
|
|
42
|
-
function createCodexDynamicToolSpecsForPromptSnapshot(params) {
|
|
43
|
-
return createCodexDynamicToolBridge({
|
|
44
|
-
tools: filterCodexDynamicTools(params.tools, params.pluginConfig ?? {}),
|
|
45
|
-
signal: new AbortController().signal,
|
|
46
|
-
loading: params.pluginConfig?.codexDynamicToolsLoading ?? "searchable",
|
|
47
|
-
directToolNames: params.directToolNames
|
|
48
|
-
}).specs;
|
|
49
|
-
}
|
|
50
|
-
//#endregion
|
|
51
|
-
export { buildCodexHarnessPromptSnapshot, createCodexDynamicToolSpecsForPromptSnapshot, resolveCodexPromptSnapshotAppServerOptions };
|