
























@@ -12,6 +12,7 @@ import {
1212isMessagingToolSendAction,
1313normalizeHeartbeatToolResponse,
1414runAgentHarnessAfterToolCallHook,
15+setBeforeToolCallDiagnosticsEnabled,
1516type AnyAgentTool,
1617type HeartbeatToolResponse,
1718type MessagingToolSend,
@@ -25,6 +26,7 @@ import {
2526type CodexDynamicToolCallOutputContentItem,
2627type CodexDynamicToolCallParams,
2728type CodexDynamicToolCallResponse,
29+type CodexDynamicToolDiagnosticTerminalType,
2830type CodexDynamicToolSpec,
2931type JsonValue,
3032} from "./protocol.js";
@@ -75,11 +77,13 @@ export function createCodexDynamicToolBridge(params: {
7577}): CodexDynamicToolBridge {
7678const toolResultHookContext = toToolResultHookContext(params.hookContext);
7779const toolResultMaxChars = resolveCodexDynamicToolResultMaxChars(params.hookContext);
78-const tools = params.tools.map((tool) =>
79-isToolWrappedWithBeforeToolCallHook(tool)
80- ? tool
81- : wrapToolWithBeforeToolCallHook(tool, params.hookContext),
82-);
80+const tools = params.tools.map((tool) => {
81+if (isToolWrappedWithBeforeToolCallHook(tool)) {
82+setBeforeToolCallDiagnosticsEnabled(tool, false);
83+return tool;
84+}
85+return wrapToolWithBeforeToolCallHook(tool, params.hookContext, { emitDiagnostics: false });
86+});
8387const toolMap = new Map(tools.map((tool) => [tool.name, tool]));
8488const telemetry: CodexDynamicToolBridge["telemetry"] = {
8589didSendViaMessagingTool: false,
@@ -163,10 +167,13 @@ export function createCodexDynamicToolBridge(params: {
163167 result,
164168 startedAt,
165169});
166-return {
167-contentItems: convertToolContents(result.content, toolResultMaxChars),
168-success: !resultIsError,
169-};
170+return withDiagnosticTerminalType(
171+{
172+contentItems: convertToolContents(result.content, toolResultMaxChars),
173+success: !resultIsError,
174+},
175+inferToolResultDiagnosticTerminalType(result, resultIsError),
176+);
170177} catch (error) {
171178collectToolTelemetry({
172179toolName: tool.name,
@@ -187,15 +194,18 @@ export function createCodexDynamicToolBridge(params: {
187194error: error instanceof Error ? error.message : String(error),
188195 startedAt,
189196});
190-return {
191-contentItems: [
192-{
193-type: "inputText",
194-text: error instanceof Error ? error.message : String(error),
195-},
196-],
197-success: false,
198-};
197+return withDiagnosticTerminalType(
198+{
199+contentItems: [
200+{
201+type: "inputText",
202+text: error instanceof Error ? error.message : String(error),
203+},
204+],
205+success: false,
206+},
207+"error",
208+);
199209}
200210},
201211};
@@ -427,6 +437,32 @@ function isToolResultError(result: AgentToolResult<unknown>): boolean {
427437);
428438}
429439440+function inferToolResultDiagnosticTerminalType(
441+result: AgentToolResult<unknown>,
442+isError: boolean,
443+): CodexDynamicToolDiagnosticTerminalType {
444+const details = result.details;
445+if (isRecord(details) && typeof details.status === "string") {
446+const status = details.status.trim().toLowerCase();
447+if (status === "blocked") {
448+return "blocked";
449+}
450+}
451+return isError ? "error" : "completed";
452+}
453+454+function withDiagnosticTerminalType<T extends CodexDynamicToolCallResponse>(
455+response: T,
456+terminalType: CodexDynamicToolDiagnosticTerminalType,
457+): T {
458+Object.defineProperty(response, "diagnosticTerminalType", {
459+configurable: true,
460+enumerable: false,
461+value: terminalType,
462+});
463+return response;
464+}
465+430466function normalizeToolResultMaxChars(maxChars: number): number {
431467return typeof maxChars === "number" && Number.isFinite(maxChars) && maxChars > 0
432468 ? Math.floor(maxChars)
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。