




























@@ -31,8 +31,13 @@ const DEFAULT_CODEX_MODEL = "openai/gpt-5.5";
31313232type TrajectoryExportApprovalEntry = {
3333id?: string;
34+command?: string;
35+commandText?: string;
36+commandPreview?: string;
3437request?: {
3538command?: string;
39+commandText?: string;
40+commandPreview?: string;
3641};
3742};
3843@@ -91,6 +96,7 @@ async function writeLiveGatewayConfig(params: {
9196port: params.port,
9297auth: { mode: "token", token: params.token },
9398},
99+commands: { ownerAllowFrom: ["*"] },
94100plugins: { allow: ["codex"] },
95101agents: {
96102list: [{ id: "dev", default: true, tools: { exec: { host: "node" } } }],
@@ -203,8 +209,21 @@ function extractAssistantTexts(messages: unknown[]): string[] {
203209return texts;
204210}
205211212+function getTrajectoryExportApprovalCommands(entry: TrajectoryExportApprovalEntry): string[] {
213+return [
214+entry.request?.command,
215+entry.request?.commandText,
216+entry.request?.commandPreview,
217+entry.command,
218+entry.commandText,
219+entry.commandPreview,
220+].filter((value): value is string => typeof value === "string" && value.trim().length > 0);
221+}
222+206223function isTrajectoryExportApproval(entry: TrajectoryExportApprovalEntry): boolean {
207-return Boolean(entry.request?.command?.includes("sessions export-trajectory"));
224+return getTrajectoryExportApprovalCommands(entry).some((command) =>
225+command.includes("sessions export-trajectory"),
226+);
208227}
209228210229function summarizeTrajectoryExportApproval(
@@ -230,6 +249,8 @@ async function waitForTrajectoryExportInstructionText(params: {
230249}): Promise<string> {
231250const deadline = Date.now() + params.timeoutMs;
232251let finalTexts: string[] = [];
252+let assistantTexts: string[] = [];
253+let nextHistoryPollAt = 0;
233254while (Date.now() < deadline) {
234255const newEvents = params.events.slice(params.eventStartIndex);
235256finalTexts = newEvents
@@ -239,25 +260,33 @@ async function waitForTrajectoryExportInstructionText(params: {
239260if (matchedText) {
240261return matchedText;
241262}
263+if (Date.now() >= nextHistoryPollAt) {
264+try {
265+const history = (await params.client.request(
266+"chat.history",
267+{
268+sessionKey: params.sessionKey,
269+limit: 24,
270+},
271+{ timeoutMs: 10_000 },
272+)) as { messages?: unknown[] };
273+assistantTexts = extractAssistantTexts(history.messages ?? []);
274+const matchedHistoryText = assistantTexts.find((text) =>
275+text.includes(params.expectedText),
276+);
277+if (matchedHistoryText) {
278+return matchedHistoryText;
279+}
280+} catch {
281+assistantTexts = [];
282+}
283+nextHistoryPollAt = Date.now() + 2_000;
284+}
242285await new Promise((resolve) => {
243286setTimeout(resolve, 500);
244287});
245288}
246-let assistantTexts: string[];
247289let approvalSummaries: TrajectoryExportApprovalSummary[];
248-try {
249-const history = (await params.client.request(
250-"chat.history",
251-{
252-sessionKey: params.sessionKey,
253-limit: 24,
254-},
255-{ timeoutMs: 10_000 },
256-)) as { messages?: unknown[] };
257-assistantTexts = extractAssistantTexts(history.messages ?? []);
258-} catch {
259-assistantTexts = [];
260-}
261290try {
262291const approvals = (await params.client.request(
263292"exec.approval.list",
@@ -348,7 +377,9 @@ async function approveTrajectoryExport(client: GatewayClient): Promise<string> {
348377`expected trajectory export approval id; approvals=${JSON.stringify(lastApprovalSummaries)}`,
349378);
350379}
351-expect(approval.request?.command).toContain("sessions export-trajectory");
380+expect(getTrajectoryExportApprovalCommands(approval).join("\n")).toContain(
381+"sessions export-trajectory",
382+);
352383await client.request(
353384"exec.approval.resolve",
354385{ id: approval.id, decision: "allow-once" },
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。