From 0445981f62e33e2c7f0d9a940d01112cc35bde3e Mon Sep 17 00:00:00 2001 From: Codex Date: Wed, 3 Jun 2026 00:43:55 +0800 Subject: [PATCH] fix: prefer current conversation thread in hwlab cli --- tools/hwlab-cli/client.test.ts | 55 ++++++++++++++++++++++++++++++++++ tools/src/hwlab-cli-lib.ts | 10 +++---- 2 files changed, 60 insertions(+), 5 deletions(-) diff --git a/tools/hwlab-cli/client.test.ts b/tools/hwlab-cli/client.test.ts index d9171ddd..86c0e5c5 100644 --- a/tools/hwlab-cli/client.test.ts +++ b/tools/hwlab-cli/client.test.ts @@ -350,6 +350,61 @@ test("hwlab-cli client agent send submits async and returns trace without waitin assert.ok(result.payload.waitPolicy.nextCommands.some((command: string) => command.includes("agent result trc_test"))); }); +test("hwlab-cli client agent send prefers selected conversation thread over stale workspace thread", async () => { + const calls: any[] = []; + const result = await runHwlabCli([ + "client", + "agent", + "send", + "--base-url", + "http://web.test", + "--cookie", + "hwlab_session=session-a", + "--message", + "continue after failed turn", + "--trace-id", + "trc_thread_current", + "--conversation-id", + "cnv_thread_current" + ], { + fetchImpl: async (url, init) => { + calls.push({ url: String(url), init, body: init?.body ? JSON.parse(String(init.body)) : null }); + if (String(url).endsWith("/v1/workbench/workspace?projectId=prj_device_pod_workbench")) { + return new Response(JSON.stringify({ + ok: true, + workspace: { + workspaceId: "wsp_thread_current", + revision: 9, + selectedConversationId: "cnv_thread_current", + selectedAgentSessionId: "ses_thread_current", + selectedConversation: { + conversationId: "cnv_thread_current", + sessionId: "ses_thread_current", + threadId: "thread-current" + }, + workspace: { + threadId: "thread-stale" + } + } + }), { status: 200 }); + } + if (String(url).endsWith("/v1/agent/chat")) { + return new Response(JSON.stringify({ accepted: true, status: "running", traceId: "trc_thread_current", resultUrl: "/v1/agent/chat/result/trc_thread_current" }), { status: 202 }); + } + return new Response(JSON.stringify({ status: "completed", traceId: "trc_thread_current", conversationId: "cnv_thread_current", reply: { role: "assistant", content: "ok" } }), { status: 200 }); + }, + sleep: async () => {} + }); + + assert.equal(result.exitCode, 0); + assert.equal(calls[1].url, "http://web.test/v1/agent/chat"); + assert.equal(calls[1].body.conversationId, "cnv_thread_current"); + assert.equal(calls[1].body.sessionId, "ses_thread_current"); + assert.equal(calls[1].body.threadId, "thread-current"); + assert.equal(result.payload.continuation.threadId, "thread-current"); + assert.equal(result.payload.workspace.threadId, "thread-current"); +}); + test("hwlab-cli client agent send waits only when --wait is explicit", async () => { const calls: any[] = []; const result = await runHwlabCli([ diff --git a/tools/src/hwlab-cli-lib.ts b/tools/src/hwlab-cli-lib.ts index 490123b9..2cee693f 100644 --- a/tools/src/hwlab-cli-lib.ts +++ b/tools/src/hwlab-cli-lib.ts @@ -1840,12 +1840,12 @@ function workbenchThreadId(workspace: any, workspaceJson: any) { const selectedAgentSession = workspace?.selectedAgentSession && typeof workspace.selectedAgentSession === "object" ? workspace.selectedAgentSession : {}; const selectedConversationJson = workspaceJson?.selectedConversation && typeof workspaceJson.selectedConversation === "object" ? workspaceJson.selectedConversation : {}; const selectedAgentSessionJson = workspaceJson?.selectedAgentSession && typeof workspaceJson.selectedAgentSession === "object" ? workspaceJson.selectedAgentSession : {}; - return text(workspaceJson?.threadId) - || text(workspace?.threadId) - || text(selectedConversation.threadId) + return text(selectedConversation.threadId ?? selectedConversation.session?.threadId) || text(selectedAgentSession.threadId) - || text(selectedConversationJson.threadId) - || text(selectedAgentSessionJson.threadId); + || text(selectedConversationJson.threadId ?? selectedConversationJson.session?.threadId) + || text(selectedAgentSessionJson.threadId) + || text(workspaceJson?.threadId) + || text(workspace?.threadId); } function workspaceSummaryFromSession(session: any) {