From 0ef13fbd6fc02154acc2b866a729fe57608fd9ad Mon Sep 17 00:00:00 2001 From: Lyon <88232613+pikasTech@users.noreply.github.com> Date: Wed, 24 Jun 2026 10:02:10 +0800 Subject: [PATCH] fix(workbench): scope agentrun pvc by hwlab session (#2035) --- internal/cloud/code-agent-agentrun-adapter.ts | 13 +++----- internal/cloud/server-agent-chat.test.ts | 30 +++++++++---------- 2 files changed, 19 insertions(+), 24 deletions(-) diff --git a/internal/cloud/code-agent-agentrun-adapter.ts b/internal/cloud/code-agent-agentrun-adapter.ts index d21600de..ea99f3fa 100644 --- a/internal/cloud/code-agent-agentrun-adapter.ts +++ b/internal/cloud/code-agent-agentrun-adapter.ts @@ -1336,7 +1336,7 @@ function buildAgentRunCreateRunInput({ params, env, traceId, backendProfile, ses valuesPrinted: false }, sessionRef: { - sessionId: sessionId ?? scopedAgentRunSessionIdForParams(params, traceId, backendProfile), + sessionId: sessionId ?? scopedAgentRunSessionIdForParams(params, traceId), ...(safeConversationId(params.conversationId) ? { conversationId: safeConversationId(params.conversationId) } : {}), ...(threadId ? { threadId } : {}), metadata: { @@ -1350,7 +1350,7 @@ function buildAgentRunCreateRunInput({ params, env, traceId, backendProfile, ses threadContinuityPolicy: THREAD_CONTINUITY_POLICY, sessionPolicy: SESSION_POLICY_RUN_LOCAL, agentRunSessionProfile: backendProfile, - agentRunSessionPolicy: "backend-profile-scoped", + agentRunSessionPolicy: "hwlab-session-scoped", valuesPrinted: false } }, @@ -3002,7 +3002,7 @@ function hwlabSessionIdForParams(params = {}) { return safeSessionId(params.sessionId) || null; } -function scopedAgentRunSessionIdForParams(params = {}, traceId, backendProfile) { +function scopedAgentRunSessionIdForParams(params = {}, traceId) { const baseSessionId = hwlabSessionIdForParams(params, traceId); if (!safeSessionId(baseSessionId)) { throw adapterError( @@ -3010,13 +3010,8 @@ function scopedAgentRunSessionIdForParams(params = {}, traceId, backendProfile) "AgentRun persistent session/PVC requires params.sessionId; refusing to derive sessionRef.sessionId from traceId because that would create a new PVC per turn." ); } - const profile = agentRunSessionProfileToken(backendProfile); const base = String(baseSessionId).replace(/^ses_/u, "").replace(/[^A-Za-z0-9_]+/gu, "_").replace(/^_+|_+$/gu, "") || "session"; - return `ses_agentrun_${profile}_${base}`; -} - -function agentRunSessionProfileToken(backendProfile) { - return String(backendProfile ?? "deepseek").trim().toLowerCase().replace(/[^a-z0-9]+/gu, "_").replace(/^_+|_+$/gu, "") || "default"; + return `ses_agentrun_${base}`; } function agentRunSessionId(traceId) { diff --git a/internal/cloud/server-agent-chat.test.ts b/internal/cloud/server-agent-chat.test.ts index 865f4d01..9f4df007 100644 --- a/internal/cloud/server-agent-chat.test.ts +++ b/internal/cloud/server-agent-chat.test.ts @@ -452,7 +452,7 @@ test("cloud api /v1/agent/chat delegates v0.3 turns to AgentRun v0.1 over adapte leaseExpiresAt: "2999-01-01T00:00:00.000Z", backendProfile: "deepseek", sessionRef: { - sessionId: "ses_agentrun_deepseek_server_test_agentrun", + sessionId: "ses_agentrun_server_test_agentrun", conversationId: "cnv_server-test-agentrun", threadId: "019e8078-db67-7750-a5d9-1a99f3abd445", metadata: {} @@ -481,11 +481,11 @@ test("cloud api /v1/agent/chat delegates v0.3 turns to AgentRun v0.1 over adapte const toolCredentials = body.executionPolicy.secretScope.toolCredentials; assert.equal(toolCredentials.some((item) => item.tool === "github" && item.projection.envName === "GH_TOKEN" && item.secretRef.name === "agentrun-v01-tool-github-pr"), true); assert.equal(toolCredentials.some((item) => item.tool === "unidesk-ssh" && item.projection.envName === "UNIDESK_SSH_CLIENT_TOKEN" && item.secretRef.name === "agentrun-v01-tool-unidesk-ssh"), true); - assert.equal(body.sessionRef.sessionId, "ses_agentrun_deepseek_server_test_agentrun"); + assert.equal(body.sessionRef.sessionId, "ses_agentrun_server_test_agentrun"); assert.equal(body.sessionRef.metadata.hwlabProjectId, "prj_hwpod_workbench"); assert.equal(body.sessionRef.metadata.hwlabSessionId, "ses_server-test-agentrun"); assert.equal(body.sessionRef.metadata.agentRunSessionProfile, "deepseek"); - assert.equal(body.sessionRef.metadata.agentRunSessionPolicy, "backend-profile-scoped"); + assert.equal(body.sessionRef.metadata.agentRunSessionPolicy, "hwlab-session-scoped"); assert.equal(body.sessionRef.metadata.threadContinuityPolicy, "hwlab-agentrun-v01-reuse-runner-thread"); assert.equal(body.sessionRef.metadata.sessionPolicy, "hwlab-agentrun-v01-session-runner-reuse"); return send({ id: "run_hwlab_adapter", status: "pending", backendProfile: "deepseek", sessionRef: body.sessionRef, resourceBundleRef: body.resourceBundleRef }); @@ -496,7 +496,7 @@ test("cloud api /v1/agent/chat delegates v0.3 turns to AgentRun v0.1 over adapte assert.equal(body.payload.targetCommandId, "cmd_hwlab_adapter"); assert.equal(body.payload.traceId, "trc_steer_server_test"); assert.match(body.payload.prompt, /STEER_MARK/u); - assert.equal(body.payload.sessionId, "ses_agentrun_deepseek_server_test_agentrun"); + assert.equal(body.payload.sessionId, "ses_agentrun_server_test_agentrun"); assert.equal(body.payload.hwlabSessionId, "ses_server-test-agentrun"); assert.equal(body.payload.threadId, "019e8078-db67-7750-a5d9-1a99f3abd445"); assert.equal(body.idempotencyKey, "trc_steer_server_test"); @@ -505,7 +505,7 @@ test("cloud api /v1/agent/chat delegates v0.3 turns to AgentRun v0.1 over adapte assert.equal(body.type, "turn"); assert.match(body.payload.prompt, /AgentRun adapter/u); assert.equal(body.payload.projectId, "prj_hwpod_workbench"); - assert.equal(body.payload.sessionId, "ses_agentrun_deepseek_server_test_agentrun"); + assert.equal(body.payload.sessionId, "ses_agentrun_server_test_agentrun"); assert.equal(body.payload.hwlabSessionId, "ses_server-test-agentrun"); assert.equal(body.payload.threadContinuityPolicy, "hwlab-agentrun-v01-reuse-runner-thread"); assert.equal(body.payload.sessionPolicy, "hwlab-agentrun-v01-session-runner-reuse"); @@ -595,7 +595,7 @@ test("cloud api /v1/agent/chat delegates v0.3 turns to AgentRun v0.1 over adapte reply: "AgentRun adapter 已接管 HWLAB Code Agent。", lastSeq: 5, eventCount: 5, - sessionRef: { sessionId: "ses_agentrun_deepseek_server_test_agentrun", conversationId: "cnv_server-test-agentrun", threadId: "019e8078-db67-7750-a5d9-1a99f3abd445" } + sessionRef: { sessionId: "ses_agentrun_server_test_agentrun", conversationId: "cnv_server-test-agentrun", threadId: "019e8078-db67-7750-a5d9-1a99f3abd445" } }); } if (request.method === "GET" && url.pathname === "/api/v1/runs/run_hwlab_adapter/commands/cmd_hwlab_adapter_second/result") { @@ -614,7 +614,7 @@ test("cloud api /v1/agent/chat delegates v0.3 turns to AgentRun v0.1 over adapte reply: "AgentRun adapter 复用已有 runner 完成第二轮。", lastSeq: 9, eventCount: 9, - sessionRef: { sessionId: "ses_agentrun_deepseek_server_test_agentrun", conversationId: "cnv_server-test-agentrun", threadId: "019e8078-db67-7750-a5d9-1a99f3abd445" } + sessionRef: { sessionId: "ses_agentrun_server_test_agentrun", conversationId: "cnv_server-test-agentrun", threadId: "019e8078-db67-7750-a5d9-1a99f3abd445" } }); } response.writeHead(404, { "content-type": "application/json" }); @@ -1698,10 +1698,10 @@ test("cloud api AgentRun adapter maps minimax-m3 provider profile to AgentRun ba }; if (request.method === "POST" && url.pathname === "/api/v1/runs") { assert.equal(body.backendProfile, "minimax-m3"); - assert.equal(body.sessionRef.sessionId, "ses_agentrun_minimax_m3_server_test_minimax_m3"); + assert.equal(body.sessionRef.sessionId, "ses_agentrun_server_test_minimax_m3"); assert.equal(body.sessionRef.metadata.hwlabSessionId, "ses_server-test-minimax-m3"); assert.equal(body.sessionRef.metadata.agentRunSessionProfile, "minimax-m3"); - assert.equal(body.sessionRef.metadata.agentRunSessionPolicy, "backend-profile-scoped"); + assert.equal(body.sessionRef.metadata.agentRunSessionPolicy, "hwlab-session-scoped"); assert.equal(body.executionPolicy.secretScope.providerCredentials[0].profile, "minimax-m3"); assert.equal(body.executionPolicy.secretScope.providerCredentials[0].secretRef.name, "agentrun-v01-provider-minimax-m3"); assert.equal(body.executionPolicy.secretScope.providerCredentials[0].secretRef.namespace, "agentrun-v01"); @@ -1709,7 +1709,7 @@ test("cloud api AgentRun adapter maps minimax-m3 provider profile to AgentRun ba } if (request.method === "POST" && url.pathname === "/api/v1/runs/run_hwlab_minimax_m3/commands") { assert.equal(body.payload.providerProfile, "minimax-m3"); - assert.equal(body.payload.sessionId, "ses_agentrun_minimax_m3_server_test_minimax_m3"); + assert.equal(body.payload.sessionId, "ses_agentrun_server_test_minimax_m3"); assert.equal(body.payload.hwlabSessionId, "ses_server-test-minimax-m3"); assert.match(body.payload.prompt, /MiniMax-M3/u); return send({ id: "cmd_hwlab_minimax_m3", runId: "run_hwlab_minimax_m3", state: "pending", type: "turn", seq: 1 }); @@ -1756,7 +1756,7 @@ test("cloud api AgentRun adapter maps minimax-m3 provider profile to AgentRun ba reply: "AGENTRUN_MINIMAX_M3_OK", lastSeq: 3, eventCount: 3, - sessionRef: { sessionId: "ses_agentrun_minimax_m3_server_test_minimax_m3", conversationId: "cnv_server-test-minimax-m3", threadId: null } + sessionRef: { sessionId: "ses_agentrun_server_test_minimax_m3", conversationId: "cnv_server-test-minimax-m3", threadId: null } }); } response.writeHead(404, { "content-type": "application/json" }); @@ -1826,7 +1826,7 @@ test("cloud api AgentRun adapter maps minimax-m3 provider profile to AgentRun ba assert.equal(payload.runner.codexStdio, false); assert.equal(payload.agentRun.backendProfile, "minimax-m3"); assert.equal(payload.sessionId, "ses_server-test-minimax-m3"); - assert.equal(payload.agentRun.sessionId, "ses_agentrun_minimax_m3_server_test_minimax_m3"); + assert.equal(payload.agentRun.sessionId, "ses_agentrun_server_test_minimax_m3"); assert.equal(payload.providerTrace.backendProfile, "minimax-m3"); assert.equal(payload.agentRun.jobName, "agentrun-v01-runner-hwlab-minimax-m3"); assert.equal(payload.reply.content, "AGENTRUN_MINIMAX_M3_OK"); @@ -1837,10 +1837,10 @@ test("cloud api AgentRun adapter maps minimax-m3 provider profile to AgentRun ba } }); -test("cloud api AgentRun adapter scopes AgentRun sessions by backend profile", async () => { +test("cloud api AgentRun adapter keeps AgentRun sessions scoped to HWLAB session across backend profile switches", async () => { const calls = []; const hwlabSessionId = "ses_server-test-profile-switch"; - const minimaxSessionId = "ses_agentrun_minimax_m3_server_test_profile_switch"; + const minimaxSessionId = "ses_agentrun_server_test_profile_switch"; const ownerSessions = new Map([[hwlabSessionId, testAgentSessionRecord({ sessionId: hwlabSessionId, conversationId: "cnv_server-test-profile-switch", @@ -1855,7 +1855,7 @@ test("cloud api AgentRun adapter scopes AgentRun sessions by backend profile", a commandId: "cmd_existing_deepseek", jobName: "agentrun-v01-runner-existing-deepseek", namespace: "agentrun-v01", - sessionId: "ses_agentrun_deepseek_server_test_profile_switch", + sessionId: "ses_agentrun_server_test_profile_switch", reuseEligible: true, managerUrl: "http://127.0.0.1:1", status: "runner-job-created"