























@@ -6,6 +6,8 @@ import type { AgentToolResult } from "openclaw/plugin-sdk/agent-core";
66import {
77createAgentToolResultMiddlewareRunner,
88createCodexAppServerToolResultExtensionRunner,
9+extractMessagingToolSend,
10+extractMessagingToolSendResult,
911extractToolResultMediaArtifact,
1012filterToolResultMediaUrls,
1113HEARTBEAT_RESPONSE_TOOL_NAME,
@@ -51,6 +53,12 @@ type CodexDynamicToolHookContext = {
5153sessionKey?: string;
5254runId?: string;
5355channelId?: string;
56+currentChannelProvider?: string;
57+currentChannelId?: string;
58+currentMessagingTarget?: string;
59+currentThreadId?: string;
60+replyToMode?: "off" | "first" | "all" | "batched";
61+hasRepliedRef?: { value: boolean };
5462};
55635664type CodexToolResultHookContext = Omit<CodexDynamicToolHookContext, "config">;
@@ -67,6 +75,22 @@ type CodexDynamicToolSchemaQuarantine = {
6775violations: readonly string[];
6876};
697778+function applyCurrentMessageProvider(
79+toolName: string,
80+args: Record<string, unknown>,
81+currentProvider: string | undefined,
82+): Record<string, unknown> {
83+const hasProvider =
84+typeof args.provider === "string" && args.provider.trim().length > 0
85+ ? true
86+ : typeof args.channel === "string" && args.channel.trim().length > 0;
87+const provider = currentProvider?.trim();
88+if (toolName !== "message" || hasProvider || !provider) {
89+return args;
90+}
91+return { ...args, provider };
92+}
93+7094/** Runtime bridge returned to Codex app-server attempt code. */
7195export type CodexDynamicToolBridge = {
7296availableSpecs: CodexDynamicToolSpec[];
@@ -213,9 +237,30 @@ export function createCodexDynamicToolBridge(params: {
213237// Prepare before marking side-effect evidence; argument preparation can
214238// fail without the target tool actually starting.
215239const preparedArgs = tool.prepareArguments ? tool.prepareArguments(args) : args;
240+const telemetryArgs = isRecord(preparedArgs) ? preparedArgs : args;
241+const messagingTelemetryArgs = applyCurrentMessageProvider(
242+toolName,
243+telemetryArgs,
244+params.hookContext?.currentChannelProvider,
245+);
246+const messagingTarget =
247+isMessagingTool(toolName) && isMessagingToolSendAction(toolName, telemetryArgs)
248+ ? extractMessagingToolSend(toolName, messagingTelemetryArgs, {
249+config: params.hookContext?.config,
250+currentChannelId: params.hookContext?.currentChannelId,
251+currentMessagingTarget: params.hookContext?.currentMessagingTarget,
252+currentThreadId: params.hookContext?.currentThreadId,
253+replyToMode: params.hookContext?.replyToMode,
254+hasRepliedRef: params.hookContext?.hasRepliedRef,
255+})
256+ : undefined;
216257didStartExecution = true;
217258const rawResult = await tool.execute(call.callId, preparedArgs, signal);
218259const rawIsError = isCodexToolResultError(rawResult);
260+const confirmedMessagingTarget =
261+!rawIsError && messagingTarget
262+ ? extractMessagingToolSendResult(messagingTarget, rawResult)
263+ : messagingTarget;
219264const middlewareResult = await middlewareRunner.applyToolResultMiddleware({
220265threadId: call.threadId,
221266turnId: call.turnId,
@@ -237,11 +282,12 @@ export function createCodexDynamicToolBridge(params: {
237282notifyAgentToolResult(options?.onAgentToolResult, toolName, result, resultIsError);
238283collectToolTelemetry({
239284 toolName,
240- args,
285+args: telemetryArgs,
241286 result,
242287mediaTrustResult: rawResult,
243288 telemetry,
244289isError: resultIsError,
290+messagingTarget: confirmedMessagingTarget,
245291});
246292void runAgentHarnessAfterToolCallHook({
247293 toolName,
@@ -631,6 +677,7 @@ function collectToolTelemetry(params: {
631677mediaTrustResult?: AgentToolResult<unknown>;
632678telemetry: CodexDynamicToolBridge["telemetry"];
633679isError: boolean;
680+messagingTarget?: MessagingToolSend;
634681}): void {
635682if (params.isError) {
636683return;
@@ -683,11 +730,13 @@ function collectToolTelemetry(params: {
683730const mediaUrls = collectMediaUrls(params.args);
684731params.telemetry.messagingToolSentMediaUrls.push(...mediaUrls);
685732params.telemetry.messagingToolSentTargets.push({
686-tool: params.toolName,
687-provider: readFirstString(params.args, ["provider", "channel"]) ?? params.toolName,
688-accountId: readFirstString(params.args, ["accountId", "account_id"]),
689-to: readFirstString(params.args, ["to", "target", "recipient"]),
690-threadId: readFirstString(params.args, ["threadId", "thread_id", "messageThreadId"]),
733+ ...(params.messagingTarget ?? {
734+tool: params.toolName,
735+provider: readFirstString(params.args, ["provider", "channel"]) ?? params.toolName,
736+accountId: readFirstString(params.args, ["accountId", "account_id"]),
737+to: readFirstString(params.args, ["to", "target", "recipient"]),
738+threadId: readFirstString(params.args, ["threadId", "thread_id", "messageThreadId"]),
739+}),
691740 ...(text ? { text } : {}),
692741 ...(mediaUrls.length > 0 ? { mediaUrls } : {}),
693742});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。