



























@@ -6,7 +6,6 @@ import { afterEach, describe, expect, it } from "vitest";
66import type { EventFrame } from "../../packages/gateway-protocol/src/index.js";
77import { isLiveTestEnabled } from "../agents/live-test-helpers.js";
88import type { OpenClawConfig } from "../config/config.js";
9-import { extractFirstTextBlock } from "../shared/chat-message-content.js";
109import { GatewayClient } from "./client.js";
1110import {
1211connectTestGatewayClient,
@@ -215,10 +214,34 @@ function extractChatFinalText(event: EventFrame, runId: string): string | undefi
215214if (!message || typeof message !== "object") {
216215return undefined;
217216}
218-const messageRecord = message as { text?: unknown };
219-return typeof messageRecord.text === "string"
220- ? messageRecord.text
221- : extractFirstTextBlock(message);
217+return extractVisibleMessageText(message);
218+}
219+220+function extractVisibleMessageText(message: unknown): string | undefined {
221+if (!message || typeof message !== "object") {
222+return undefined;
223+}
224+const record = message as { text?: unknown; content?: unknown };
225+if (typeof record.text === "string" && record.text.trim()) {
226+return record.text;
227+}
228+if (typeof record.content === "string" && record.content.trim()) {
229+return record.content;
230+}
231+if (!Array.isArray(record.content)) {
232+return undefined;
233+}
234+const text = record.content
235+.map((block) => {
236+if (!block || typeof block !== "object") {
237+return "";
238+}
239+const entry = block as { type?: unknown; text?: unknown };
240+return entry.type === "text" && typeof entry.text === "string" ? entry.text : "";
241+})
242+.filter((value) => value.trim())
243+.join("\n");
244+return text || undefined;
222245}
223246224247async function approveTrajectoryExport(client: GatewayClient): Promise<string> {
@@ -231,7 +254,7 @@ async function approveTrajectoryExport(client: GatewayClient): Promise<string> {
231254};
232255}
233256| undefined;
234-let lastApprovalCommands: string[] = [];
257+let lastApprovalSummaries: Array<{ id?: string; hasTrajectoryExportCommand: boolean }> = [];
235258while (Date.now() - startedAt < 60_000) {
236259const approvals = (await client.request(
237260"exec.approval.list",
@@ -243,9 +266,12 @@ async function approveTrajectoryExport(client: GatewayClient): Promise<string> {
243266command?: string;
244267};
245268}>;
246-lastApprovalCommands = approvals
247-.map((entry) => entry.request?.command)
248-.filter((command): command is string => typeof command === "string");
269+lastApprovalSummaries = approvals.map((entry) => ({
270+ ...(entry.id ? { id: entry.id } : {}),
271+hasTrajectoryExportCommand: Boolean(
272+entry.request?.command?.includes("sessions export-trajectory"),
273+),
274+}));
249275approval = approvals.find((entry) =>
250276entry.request?.command?.includes("sessions export-trajectory"),
251277);
@@ -258,7 +284,7 @@ async function approveTrajectoryExport(client: GatewayClient): Promise<string> {
258284}
259285if (!approval?.id) {
260286throw new Error(
261-`expected trajectory export approval id; approvals=${JSON.stringify(lastApprovalCommands)}`,
287+`expected trajectory export approval id; approvals=${JSON.stringify(lastApprovalSummaries)}`,
262288);
263289}
264290expect(approval.request?.command).toContain("sessions export-trajectory");
@@ -387,7 +413,7 @@ describeLive("gateway live trajectory export", () => {
387413).toBe(true);
388414const finalText =
389415typeof exportResponse?.message === "object"
390- ? extractFirstTextBlock(exportResponse.message)
416+ ? extractVisibleMessageText(exportResponse.message)
391417 : await waitForTrajectoryExportInstructionText({
392418events: gatewayEvents,
393419expectedText: "Trajectory exports can include",
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。