






















@@ -87,12 +87,14 @@ export function createCodexDynamicToolBridge(params: {
8787try {
8888const preparedArgs = tool.prepareArguments ? tool.prepareArguments(args) : args;
8989const rawResult = await tool.execute(call.callId, preparedArgs, params.signal);
90+const rawIsError = isToolResultError(rawResult);
9091const middlewareResult = await middlewareRunner.applyToolResultMiddleware({
9192threadId: call.threadId,
9293turnId: call.turnId,
9394toolCallId: call.callId,
9495toolName: tool.name,
9596 args,
97+isError: rawIsError,
9698result: rawResult,
9799});
98100const result = await legacyExtensionRunner.applyToolResultExtensions({
@@ -107,8 +109,9 @@ export function createCodexDynamicToolBridge(params: {
107109toolName: tool.name,
108110 args,
109111 result,
112+mediaTrustResult: rawResult,
110113 telemetry,
111-isError: false,
114+isError: rawIsError || isToolResultError(result),
112115});
113116void runAgentHarnessAfterToolCallHook({
114117toolName: tool.name,
@@ -162,6 +165,7 @@ function collectToolTelemetry(params: {
162165toolName: string;
163166args: Record<string, unknown>;
164167result: AgentToolResult<unknown> | undefined;
168+mediaTrustResult?: AgentToolResult<unknown>;
165169telemetry: CodexDynamicToolBridge["telemetry"];
166170isError: boolean;
167171}): void {
@@ -174,7 +178,11 @@ function collectToolTelemetry(params: {
174178if (!params.isError && params.result) {
175179const media = extractToolResultMediaArtifact(params.result);
176180if (media) {
177-const mediaUrls = filterToolResultMediaUrls(params.toolName, media.mediaUrls, params.result);
181+const mediaUrls = filterToolResultMediaUrls(
182+params.toolName,
183+media.mediaUrls,
184+params.mediaTrustResult ?? params.result,
185+);
178186const seen = new Set(params.telemetry.toolMediaUrls);
179187for (const mediaUrl of mediaUrls) {
180188if (!seen.has(mediaUrl)) {
@@ -208,6 +216,35 @@ function collectToolTelemetry(params: {
208216});
209217}
210218219+function isRecord(value: unknown): value is Record<string, unknown> {
220+return value !== null && typeof value === "object" && !Array.isArray(value);
221+}
222+223+function isToolResultError(result: AgentToolResult<unknown>): boolean {
224+const details = result.details;
225+if (!isRecord(details)) {
226+return false;
227+}
228+if (details.timedOut === true) {
229+return true;
230+}
231+if (typeof details.exitCode === "number" && details.exitCode !== 0) {
232+return true;
233+}
234+if (typeof details.status !== "string") {
235+return false;
236+}
237+const status = details.status.trim().toLowerCase();
238+return (
239+status !== "" &&
240+status !== "0" &&
241+status !== "ok" &&
242+status !== "success" &&
243+status !== "completed" &&
244+status !== "running"
245+);
246+}
247+211248function convertToolContent(
212249content: TextContent | ImageContent,
213250): CodexDynamicToolCallOutputContentItem[] {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。