fix(workbench): scope agentrun pvc by hwlab session (#2035)

This commit is contained in:
Lyon
2026-06-24 10:02:10 +08:00
committed by GitHub
parent 7d80770e40
commit 0ef13fbd6f
2 changed files with 19 additions and 24 deletions
@@ -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) {
+15 -15
View File
@@ -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"