Fix Jupyter workspace session handoff
This commit is contained in:
@@ -20,6 +20,7 @@ import {
|
||||
SidebarTrigger,
|
||||
} from "@/components/ui/sidebar";
|
||||
import {
|
||||
consumePendingWorkspaceSessionId,
|
||||
readActiveSessionId,
|
||||
writeActiveSessionId,
|
||||
} from "@/lib/claw-active-session";
|
||||
@@ -37,10 +38,21 @@ export const Assistant = () => {
|
||||
const messages = options.messages as UIMessage[];
|
||||
const selectedSessionId = readActiveSessionId();
|
||||
const lastSessionId = getLastSessionId(messages);
|
||||
const pendingWorkspaceSessionId =
|
||||
messages.length <= 1 ? consumePendingWorkspaceSessionId() : null;
|
||||
const usablePendingWorkspaceSessionId =
|
||||
pendingWorkspaceSessionId &&
|
||||
(!selectedSessionId ||
|
||||
selectedSessionId === pendingWorkspaceSessionId)
|
||||
? pendingWorkspaceSessionId
|
||||
: null;
|
||||
const selectedResumeSessionId =
|
||||
messages.length > 1 ? selectedSessionId : null;
|
||||
const outgoingSessionId =
|
||||
lastSessionId ?? selectedResumeSessionId ?? options.id;
|
||||
lastSessionId ??
|
||||
selectedResumeSessionId ??
|
||||
usablePendingWorkspaceSessionId ??
|
||||
options.id;
|
||||
const lastUserMessage = [...messages]
|
||||
.reverse()
|
||||
.find((message) => message.role === "user");
|
||||
@@ -49,7 +61,7 @@ export const Assistant = () => {
|
||||
return {
|
||||
body: {
|
||||
...body,
|
||||
id: options.id,
|
||||
id: outgoingSessionId,
|
||||
messages: lastUserMessage ? [lastUserMessage] : [],
|
||||
resumeSessionId:
|
||||
lastSessionId ?? selectedResumeSessionId ?? undefined,
|
||||
|
||||
@@ -83,6 +83,7 @@ import {
|
||||
clearActiveSessionId,
|
||||
readActiveSessionId,
|
||||
writeActiveSessionId,
|
||||
writePendingWorkspaceSessionId,
|
||||
} from "@/lib/claw-active-session";
|
||||
import { useClawSessionReplay } from "@/lib/claw-session-replay";
|
||||
import { cn } from "@/lib/utils";
|
||||
@@ -437,6 +438,7 @@ function WorkspaceSwitchDialog({
|
||||
setSubmitting(true);
|
||||
const progressTimer = startWorkspaceProgress(setProgress);
|
||||
try {
|
||||
const needsFirstMessageSession = !normalizeSessionId(sessionId);
|
||||
const response = await fetch("/api/claw/jupyter", {
|
||||
method: "POST",
|
||||
headers: { "content-type": "application/json" },
|
||||
@@ -455,6 +457,9 @@ function WorkspaceSwitchDialog({
|
||||
return;
|
||||
}
|
||||
writeActiveSessionId(sessionIdForRequest);
|
||||
if (needsFirstMessageSession) {
|
||||
writePendingWorkspaceSessionId(sessionIdForRequest);
|
||||
}
|
||||
setStatus(payload as JupyterWorkspaceStatus);
|
||||
setProgress({ percent: 100, label: "切换完成" });
|
||||
setMessage("工作区切换成功,后续工具会在远端 Jupyter 工作区执行。");
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
"use client";
|
||||
|
||||
const ACTIVE_SESSION_ID_KEY = "claw.activeSessionId";
|
||||
const PENDING_WORKSPACE_SESSION_ID_KEY = "claw.pendingWorkspaceSessionId";
|
||||
export const ACTIVE_SESSION_CHANGED_EVENT = "claw-active-session-changed";
|
||||
|
||||
export function readActiveSessionId() {
|
||||
@@ -20,6 +21,10 @@ export function writeActiveSessionId(sessionId: string | null | undefined) {
|
||||
}
|
||||
window.sessionStorage.setItem(ACTIVE_SESSION_ID_KEY, normalized);
|
||||
window.localStorage.setItem(ACTIVE_SESSION_ID_KEY, normalized);
|
||||
const pendingSessionId = readPendingWorkspaceSessionId();
|
||||
if (pendingSessionId && pendingSessionId !== normalized) {
|
||||
clearPendingWorkspaceSessionId();
|
||||
}
|
||||
window.dispatchEvent(
|
||||
new CustomEvent(ACTIVE_SESSION_CHANGED_EVENT, {
|
||||
detail: { sessionId: normalized },
|
||||
@@ -31,6 +36,7 @@ export function clearActiveSessionId() {
|
||||
if (typeof window === "undefined") return;
|
||||
window.sessionStorage.removeItem(ACTIVE_SESSION_ID_KEY);
|
||||
window.localStorage.removeItem(ACTIVE_SESSION_ID_KEY);
|
||||
clearPendingWorkspaceSessionId();
|
||||
window.dispatchEvent(
|
||||
new CustomEvent(ACTIVE_SESSION_CHANGED_EVENT, {
|
||||
detail: { sessionId: null },
|
||||
@@ -38,6 +44,43 @@ export function clearActiveSessionId() {
|
||||
);
|
||||
}
|
||||
|
||||
export function writePendingWorkspaceSessionId(
|
||||
sessionId: string | null | undefined,
|
||||
) {
|
||||
if (typeof window === "undefined") return;
|
||||
const normalized = normalizeSessionId(sessionId);
|
||||
if (!normalized) {
|
||||
clearPendingWorkspaceSessionId();
|
||||
return;
|
||||
}
|
||||
window.sessionStorage.setItem(PENDING_WORKSPACE_SESSION_ID_KEY, normalized);
|
||||
window.localStorage.setItem(PENDING_WORKSPACE_SESSION_ID_KEY, normalized);
|
||||
}
|
||||
|
||||
export function consumePendingWorkspaceSessionId() {
|
||||
const sessionId = readPendingWorkspaceSessionId();
|
||||
clearPendingWorkspaceSessionId();
|
||||
return sessionId;
|
||||
}
|
||||
|
||||
function readPendingWorkspaceSessionId() {
|
||||
if (typeof window === "undefined") return null;
|
||||
return (
|
||||
normalizeSessionId(
|
||||
window.sessionStorage.getItem(PENDING_WORKSPACE_SESSION_ID_KEY),
|
||||
) ??
|
||||
normalizeSessionId(
|
||||
window.localStorage.getItem(PENDING_WORKSPACE_SESSION_ID_KEY),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function clearPendingWorkspaceSessionId() {
|
||||
if (typeof window === "undefined") return;
|
||||
window.sessionStorage.removeItem(PENDING_WORKSPACE_SESSION_ID_KEY);
|
||||
window.localStorage.removeItem(PENDING_WORKSPACE_SESSION_ID_KEY);
|
||||
}
|
||||
|
||||
function normalizeSessionId(value: unknown) {
|
||||
if (typeof value !== "string") return null;
|
||||
const trimmed = value.trim();
|
||||
|
||||
Reference in New Issue
Block a user