代码提交
This commit is contained in:
1 parent
49af497085
commit
3eb307c5c5
155 files changed
+4706
-100
No files matched your search
@@ -24,11 +24,23 @@
|
||||
|
||||
| 参数 | 是否必填 | 作用 |
|
||||
| --- | --- | --- |
|
||||
| `taskId` | 否 | 外部任务 ID。缺失时使用本地 mock 任务,便于演示和开发。 |
|
||||
| `taskId` | 否 | 外部任务 ID。传入后它是岗位会商的共享存储作用域;缺失时保持原有的个人会话逻辑。mock 仅提供任务卡片的显示兜底,绝不替换路由传入的 ID。 |
|
||||
| `sessionId` | 否 | 直接恢复指定岗位会商会话;缺失时页面会按 `taskId` 查找最近一条未归档会话。 |
|
||||
| `positionId` | 否 | 初始打开的岗位,同时同步顶部岗位选择器。无效值回退到 `intelligence`。 |
|
||||
| `new=1` | 否 | 强制不恢复历史会话,以新会话开始。 |
|
||||
|
||||
传入 `taskId` 时,同一个任务下可以有多条会商会话,所有用户共享同一份历史、节点快照与 LangGraph 线程;当前 `user_id` 仅保留创建审计,不参与这些任务会话的读写过滤。页面恢复 `sessionId` 时会核验其 `externalTaskId` 与路由 `taskId` 一致,不一致会丢弃该会话并按当前任务重新发现历史。未传 `taskId` 时,会继续只读取当前用户的原有个人会话。
|
||||
|
||||
### 外部系统按 taskId 对接
|
||||
|
||||
1. 进入页面时将业务侧任务的稳定主键原样放入 URL。工作区入口使用 `/#/page/workspace/roundtable/position?taskId=<taskId>`;策略页入口也兼容 `/#/page/strategy/qa/position-roundtable?taskId=<taskId>`。不要使用任务标题、序号或每次请求都变化的临时 ID。
|
||||
2. 前端先调用 `GET /api/position-roundtable/sessions?external_task_id=<taskId>`;返回的是该任务下所有用户共享的会商记录,按最近更新时间排序。选中一条后再调用 `GET /sessions/{sessionId}` 恢复完整节点和聊天快照。
|
||||
3. 没有可恢复记录时,调用 `POST /sessions`,至少传入 `{ external_task_id: taskId, task_snapshot: { ...任务展示字段 } }`。服务端将 `task_scoped` 设为 `true`,并固定快照中的 `id` / `externalTaskId` 为传入的 taskId。
|
||||
4. 后续所有意图、链条、节点、收口智能体和历史删除 API 只使用返回的 `sessionId`;不要在每次消息请求中重新创建会话。一个 taskId 可以有多条 sessionId。
|
||||
5. 不传 `taskId`(同时省略 `external_task_id`)就是兼容模式:后端只返回和操作当前用户自己的个人会话,绝不会把历史记录升级为共享。响应中的 `task_scoped` 可用来区分两种记录。
|
||||
|
||||
服务端从请求中的非空 `external_task_id` 判断是否开启共享,调用方无需也不应自行传 `task_scoped`。
|
||||
|
||||
当前岗位 ID 定义在 `lib/positions.ts`:
|
||||
|
||||
| ID | 页面岗位 | 职责 |
|
||||
@@ -132,8 +144,9 @@ PositionRoundtablePage
|
||||
|
||||
页面只维护一个 `sandboxArtifact`。`PositionNodeChat` 和 `PositionBuiltinAgentChat` 通过 `onPreviewArtifact` 上报预览目标;父页面统一渲染 `ArtifactFileDetail`。
|
||||
|
||||
**对接 / 重做页面 / 排障指南(接口约定、必守规则、自测与症状表):**
|
||||
[`docs/沙箱打开关闭与步骤条.md`](./docs/沙箱打开关闭与步骤条.md)
|
||||
**对接 / 重做页面 / 排障指南(打开关闭时机、步骤条、接口约定):**
|
||||
[`../../docs/position-roundtable-sandbox/沙箱打开关闭与步骤条.md`](../../docs/position-roundtable-sandbox/沙箱打开关闭与步骤条.md)
|
||||
(目录说明见 [`../../docs/position-roundtable-sandbox/README.md`](../../docs/position-roundtable-sandbox/README.md))
|
||||
|
||||
设计要点:
|
||||
|
||||
@@ -163,8 +176,8 @@ PositionRoundtablePage
|
||||
|
||||
| 方法 | 路径 | 用途 |
|
||||
| --- | --- | --- |
|
||||
| `GET` | `/sessions?external_task_id=` | 按任务查询会话,用于恢复最近会话和历史记录。 |
|
||||
| `POST` | `/sessions` | 创建初始会话并保存任务快照。 |
|
||||
| `GET` | `/sessions?external_task_id=<taskId>` | 传入时按任务作用域查询共享会话;不传参数时查询当前用户的个人历史。 |
|
||||
| `POST` | `/sessions` | 创建会话并保存任务快照;传入非空 `external_task_id` 时服务端会将快照 ID 固定为该值并启用共享;缺失或空值时创建原有个人会话。 |
|
||||
| `GET` | `/sessions/{id}` | 恢复会话、节点和冻结快照。 |
|
||||
| `DELETE` | `/sessions/{id}` | 删除一条岗位会商历史及其节点;删除当前记录时前端会先屏蔽并发恢复请求。 |
|
||||
| `PUT` | `/sessions/{id}/task` | 更新未冻结的任务快照。 |
|
||||
@@ -178,7 +191,7 @@ PositionRoundtablePage
|
||||
| `POST` | `/sessions/{id}/summary/*` | 准备、发送和完成方案总结。 |
|
||||
| `POST` | `/sessions/{id}/action-plan/*` | 准备、发送和完成行动规划。 |
|
||||
| `PUT` | `/sessions/{id}/{summary|action-plan}/conversation` | 保存两个收口智能体的消息与未发送草稿。 |
|
||||
| `POST` | `/demo/seed` | 按用户和 `demoKey` 幂等初始化完整演示会话。 |
|
||||
| `POST` | `/demo/seed` | 按 `demoKey` 幂等初始化完整演示会话。 |
|
||||
|
||||
后端实现在 `offline-backend-20260512/backend/app/gateway/routers/position_roundtable.py`。
|
||||
|
||||
|
||||
@@ -68,7 +68,10 @@ export interface PositionRoundtableNode {
|
||||
*/
|
||||
export interface PositionRoundtableSession {
|
||||
id: string;
|
||||
/** Present only when the workspace was opened with a route `taskId`. */
|
||||
externalTaskId: string | null;
|
||||
/** True only for sessions intentionally shared by an explicit route taskId. */
|
||||
taskScoped: boolean;
|
||||
taskSnapshot: Record<string, unknown>;
|
||||
chainId: string | null;
|
||||
chainSnapshot: Record<string, unknown> | null;
|
||||
@@ -112,6 +115,7 @@ interface ServerNode {
|
||||
interface ServerSession {
|
||||
id: string;
|
||||
external_task_id: string | null;
|
||||
task_scoped?: boolean;
|
||||
task_snapshot?: Record<string, unknown>;
|
||||
chain_id: string | null;
|
||||
chain_snapshot?: Record<string, unknown> | null;
|
||||
@@ -270,6 +274,7 @@ function toSession(session: ServerSession): PositionRoundtableSession {
|
||||
const result: PositionRoundtableSession = {
|
||||
id: session.id,
|
||||
externalTaskId: session.external_task_id,
|
||||
taskScoped: session.task_scoped ?? false,
|
||||
taskSnapshot: session.task_snapshot ?? {},
|
||||
chainId: session.chain_id,
|
||||
chainSnapshot: session.chain_snapshot ?? null,
|
||||
|
||||
@@ -31,16 +31,21 @@ export const MOCK_POSITION_TASKS: readonly PositionTask[] = [
|
||||
export const DEFAULT_MOCK_POSITION_TASK_ID = MOCK_POSITION_TASKS[0].id;
|
||||
|
||||
export function getMockPositionTask(taskId?: string | null): PositionTask {
|
||||
return (
|
||||
const fixture =
|
||||
MOCK_POSITION_TASKS.find((task) => task.id === taskId) ??
|
||||
MOCK_POSITION_TASKS[0]
|
||||
);
|
||||
MOCK_POSITION_TASKS[0];
|
||||
const scopedTaskId = taskId?.trim();
|
||||
// The fixture supplies only display defaults. Preserve the caller's task
|
||||
// identity so persistence, history and LangGraph thread metadata all remain
|
||||
// bound to the route taskId.
|
||||
return scopedTaskId ? { ...fixture, id: scopedTaskId } : fixture;
|
||||
}
|
||||
|
||||
/** Normalizes a persisted Session task snapshot without exposing source internals. */
|
||||
export function taskFromPositionSnapshot(
|
||||
snapshot: Record<string, unknown> | null | undefined,
|
||||
fallback: PositionTask,
|
||||
taskScopeId?: string,
|
||||
): PositionTask {
|
||||
if (!snapshot || Object.keys(snapshot).length === 0) return fallback;
|
||||
const value = (keys: string[], defaultValue: string) => {
|
||||
@@ -50,7 +55,11 @@ export function taskFromPositionSnapshot(
|
||||
return typeof found === "string" ? found : defaultValue;
|
||||
};
|
||||
return {
|
||||
id: value(["id", "taskId", "externalTaskId"], fallback.id),
|
||||
// Session snapshots are editable display data, while the route taskId is
|
||||
// the stable shared-storage scope. Keeping them separate prevents a
|
||||
// legacy/mock snapshot from moving a live external task into another
|
||||
// task's history bucket.
|
||||
id: taskScopeId?.trim() || value(["id", "taskId", "externalTaskId"], fallback.id),
|
||||
title: value(["title", "taskName", "name"], fallback.title),
|
||||
description: value(["description", "taskContent", "overview", "content"], fallback.description),
|
||||
direction: value(["direction", "taskDirection", "category"], fallback.direction),
|
||||
|
||||
@@ -140,6 +140,7 @@ import {
|
||||
getPositionSession,
|
||||
isPositionSessionNotFoundError,
|
||||
listPositionSessions,
|
||||
PositionSessionNotFoundError,
|
||||
preparePositionActionPlan,
|
||||
preparePositionSummary,
|
||||
rejectPositionNode,
|
||||
@@ -182,6 +183,18 @@ type PositionArtifactPreview = {
|
||||
previewKey?: string;
|
||||
auto?: boolean;
|
||||
};
|
||||
|
||||
function isSessionInTaskScope(
|
||||
session: PositionRoundtableSession,
|
||||
taskScopeId: string | null,
|
||||
): boolean {
|
||||
// The legacy entry has no taskId and remains user-owned. Explicit taskId
|
||||
// deep links are the only shared mode and must never cross task scopes.
|
||||
return taskScopeId === null
|
||||
? !session.taskScoped
|
||||
: session.taskScoped && session.externalTaskId === taskScopeId;
|
||||
}
|
||||
|
||||
type ClosureStageKind = PositionBuiltinAgentKind;
|
||||
type IntentEditDraft = {
|
||||
objective: string;
|
||||
@@ -829,18 +842,21 @@ export default function PositionRoundtablePage({
|
||||
const [positionId, setPositionId] = useState<PositionId>(() => positionIdFromUrl);
|
||||
const demoModeEnabled = isPositionRoundtableDemoEnabled();
|
||||
const demoTask = useMemo(() => getPositionDemoTask(), []);
|
||||
const taskIdFromUrl =
|
||||
// A route taskId opts into shared task collaboration. Without it this page
|
||||
// keeps the original personal-session behavior and uses mock data only for
|
||||
// display defaults.
|
||||
const taskScopeId =
|
||||
standaloneDemoMode
|
||||
? demoTask.id
|
||||
: searchParams.get("taskId") ??
|
||||
(demoModeEnabled ? demoTask.id : DEFAULT_MOCK_POSITION_TASK_ID);
|
||||
: searchParams.get("taskId")?.trim() || null;
|
||||
const displayTaskId = taskScopeId ?? (demoModeEnabled ? demoTask.id : DEFAULT_MOCK_POSITION_TASK_ID);
|
||||
const searchParamsString = searchParams.toString();
|
||||
const fallbackTask = useMemo(
|
||||
() =>
|
||||
demoModeEnabled && taskIdFromUrl === demoTask.id
|
||||
demoModeEnabled && displayTaskId === demoTask.id
|
||||
? demoTask
|
||||
: getMockPositionTask(taskIdFromUrl),
|
||||
[demoModeEnabled, demoTask, taskIdFromUrl],
|
||||
: getMockPositionTask(displayTaskId),
|
||||
[demoModeEnabled, demoTask, displayTaskId],
|
||||
);
|
||||
const rawSessionIdFromUrl = searchParams.get("sessionId");
|
||||
const sessionIdFromUrl =
|
||||
@@ -1033,8 +1049,8 @@ export default function PositionRoundtablePage({
|
||||
[positionSession?.intentSnapshot],
|
||||
);
|
||||
const task = useMemo(
|
||||
() => taskFromPositionSnapshot(positionSession?.taskSnapshot, fallbackTask),
|
||||
[fallbackTask, positionSession?.taskSnapshot],
|
||||
() => taskFromPositionSnapshot(positionSession?.taskSnapshot, fallbackTask, taskScopeId ?? undefined),
|
||||
[fallbackTask, positionSession?.taskSnapshot, taskScopeId],
|
||||
);
|
||||
const intentTaskContext = useMemo(
|
||||
() => ({
|
||||
@@ -1144,9 +1160,10 @@ export default function PositionRoundtablePage({
|
||||
positionSession?.status === "archived";
|
||||
|
||||
const syncSessionUrl = useCallback(
|
||||
(sessionId: string, nextTaskId: string) => {
|
||||
(sessionId: string, nextTaskId?: string | null) => {
|
||||
const next = new URLSearchParams(searchParamsString);
|
||||
next.set("taskId", nextTaskId);
|
||||
if (nextTaskId) next.set("taskId", nextTaskId);
|
||||
else next.delete("taskId");
|
||||
next.set("sessionId", sessionId);
|
||||
next.delete("new");
|
||||
setSearchParams(next, { replace: true });
|
||||
@@ -1162,20 +1179,20 @@ export default function PositionRoundtablePage({
|
||||
const localSession = getLocalPositionDemoSession();
|
||||
positionSessionRef.current = localSession;
|
||||
setPositionSession(localSession);
|
||||
syncSessionUrl(localSession.id, localSession.externalTaskId ?? taskSnapshot.id);
|
||||
syncSessionUrl(localSession.id, taskScopeId);
|
||||
return localSession;
|
||||
}
|
||||
if (sessionCreationRef.current) return sessionCreationRef.current;
|
||||
const creation = createPositionSession({
|
||||
externalTaskId: taskSnapshot.id || undefined,
|
||||
taskSnapshot: { ...taskSnapshot },
|
||||
externalTaskId: taskScopeId ?? undefined,
|
||||
taskSnapshot: taskScopeId ? { ...taskSnapshot, id: taskScopeId } : { ...taskSnapshot },
|
||||
})
|
||||
.then((created) => {
|
||||
// Update the ref synchronously. Several effects can observe a new
|
||||
// intent thread in the same render cycle; all must share this row.
|
||||
positionSessionRef.current = created;
|
||||
setPositionSession(created);
|
||||
syncSessionUrl(created.id, taskSnapshot.id);
|
||||
syncSessionUrl(created.id, taskScopeId);
|
||||
return created;
|
||||
})
|
||||
.finally(() => {
|
||||
@@ -1186,7 +1203,7 @@ export default function PositionRoundtablePage({
|
||||
sessionCreationRef.current = creation;
|
||||
return creation;
|
||||
},
|
||||
[standaloneDemoMode, syncSessionUrl],
|
||||
[standaloneDemoMode, syncSessionUrl, taskScopeId],
|
||||
);
|
||||
|
||||
const openTaskEditor = useCallback(() => {
|
||||
@@ -1207,6 +1224,10 @@ export default function PositionRoundtablePage({
|
||||
}
|
||||
const nextTask: PositionTask = {
|
||||
...task,
|
||||
// Task identity comes exclusively from the route. Task-card editing can
|
||||
// change display fields but must never move this session to another
|
||||
// shared task bucket.
|
||||
id: taskScopeId ?? task.id,
|
||||
title,
|
||||
priority: taskDraft.priority?.trim() || task.priority || "紧急",
|
||||
description: taskDraft.description.trim(),
|
||||
@@ -1225,7 +1246,7 @@ export default function PositionRoundtablePage({
|
||||
positionSessionRef.current = merged;
|
||||
return merged;
|
||||
});
|
||||
syncSessionUrl(saved.id, nextTask.id);
|
||||
syncSessionUrl(saved.id, taskScopeId);
|
||||
setTaskEditorOpen(false);
|
||||
toast.success("任务信息已更新");
|
||||
} catch (error) {
|
||||
@@ -1233,7 +1254,7 @@ export default function PositionRoundtablePage({
|
||||
} finally {
|
||||
setTaskSaving(false);
|
||||
}
|
||||
}, [ensureEditableSession, isArchivedSession, syncSessionUrl, task, taskDraft]);
|
||||
}, [ensureEditableSession, isArchivedSession, syncSessionUrl, task, taskDraft, taskScopeId]);
|
||||
|
||||
const openIntentEditor = useCallback(() => {
|
||||
if (isArchivedSession) return;
|
||||
@@ -1524,7 +1545,7 @@ export default function PositionRoundtablePage({
|
||||
let cancelled = false;
|
||||
void getPositionSession(sessionIdFromUrl)
|
||||
.then((session) => {
|
||||
if (!cancelled) {
|
||||
if (!cancelled && isSessionInTaskScope(session, taskScopeId)) {
|
||||
positionSessionRef.current = session;
|
||||
setPositionSession(session);
|
||||
}
|
||||
@@ -1533,7 +1554,7 @@ export default function PositionRoundtablePage({
|
||||
return () => {
|
||||
cancelled = true;
|
||||
};
|
||||
}, [positionSession, sessionIdFromUrl]);
|
||||
}, [positionSession, sessionIdFromUrl, taskScopeId]);
|
||||
const handleNodeUpdate = useCallback((updatedNode: PositionRoundtableNode) => {
|
||||
setPositionSession((current) => {
|
||||
if (!current?.nodes) return current;
|
||||
@@ -1812,15 +1833,17 @@ export default function PositionRoundtablePage({
|
||||
);
|
||||
const openPositionConfig = useCallback(
|
||||
(chainId: string) => {
|
||||
const taskQuery = `taskId=${encodeURIComponent(task.id)}${forceNewSession ? "&new=1" : ""}`;
|
||||
const returnTo = sessionIdFromUrl
|
||||
? `/page/strategy/qa/position-roundtable?${taskQuery}&sessionId=${encodeURIComponent(sessionIdFromUrl)}`
|
||||
: `/page/strategy/qa/position-roundtable?${taskQuery}`;
|
||||
const returnParams = new URLSearchParams();
|
||||
if (taskScopeId) returnParams.set("taskId", taskScopeId);
|
||||
if (forceNewSession) returnParams.set("new", "1");
|
||||
if (sessionIdFromUrl) returnParams.set("sessionId", sessionIdFromUrl);
|
||||
const returnQuery = returnParams.toString();
|
||||
const returnTo = `/page/strategy/qa/position-roundtable${returnQuery ? `?${returnQuery}` : ""}`;
|
||||
navigate(
|
||||
`/page/workspace/roundtable/chains?chainId=${encodeURIComponent(chainId)}&mode=position&returnTo=${encodeURIComponent(returnTo)}`,
|
||||
);
|
||||
},
|
||||
[forceNewSession, navigate, sessionIdFromUrl, task.id],
|
||||
[forceNewSession, navigate, sessionIdFromUrl, taskScopeId],
|
||||
);
|
||||
|
||||
// The mock task source mirrors the future external-task contract: opening a
|
||||
@@ -1843,7 +1866,7 @@ export default function PositionRoundtablePage({
|
||||
const useDemoFixture = demoModeEnabled && task.id === demoTask.id;
|
||||
const discovery = useDemoFixture
|
||||
? initializePositionRoundtableDemo().then((session) => [session])
|
||||
: listPositionSessions(task.id);
|
||||
: listPositionSessions(taskScopeId ?? undefined);
|
||||
void discovery
|
||||
.then((sessions) => {
|
||||
if (cancelled) return;
|
||||
@@ -1861,7 +1884,8 @@ export default function PositionRoundtablePage({
|
||||
setSessionDiscoveryDone(true);
|
||||
}
|
||||
const next = new URLSearchParams(searchParamsString);
|
||||
next.set("taskId", task.id);
|
||||
if (taskScopeId) next.set("taskId", taskScopeId);
|
||||
else next.delete("taskId");
|
||||
next.set("sessionId", latest.id);
|
||||
setSearchParams(next, { replace: true });
|
||||
})
|
||||
@@ -1881,7 +1905,7 @@ export default function PositionRoundtablePage({
|
||||
searchParamsString,
|
||||
sessionIdFromUrl,
|
||||
setSearchParams,
|
||||
task.id,
|
||||
taskScopeId,
|
||||
]);
|
||||
|
||||
// Create the database row as soon as discovery confirms this is a new task
|
||||
@@ -1928,6 +1952,11 @@ export default function PositionRoundtablePage({
|
||||
: getPositionSession(sessionIdFromUrl);
|
||||
void request
|
||||
.then((session) => {
|
||||
if (!isSessionInTaskScope(session, taskScopeId)) {
|
||||
// A shared session id can be pasted with the wrong taskId. Treat it
|
||||
// as stale navigation instead of allowing it to cross task scopes.
|
||||
throw new PositionSessionNotFoundError(sessionIdFromUrl);
|
||||
}
|
||||
if (
|
||||
!cancelled &&
|
||||
!ignoredSessionLoadIdsRef.current.has(sessionIdFromUrl)
|
||||
@@ -1966,7 +1995,7 @@ export default function PositionRoundtablePage({
|
||||
return () => {
|
||||
cancelled = true;
|
||||
};
|
||||
}, [searchParamsString, sessionIdFromUrl, setSearchParams]);
|
||||
}, [searchParamsString, sessionIdFromUrl, setSearchParams, taskScopeId]);
|
||||
|
||||
const agentIdForPanel = activePosition.isIntentPosition ? INTENT_AGENT_ID : selectedAgentId;
|
||||
const { agent: selectedAgent } = useAgent(agentIdForPanel, {
|
||||
@@ -2061,7 +2090,8 @@ export default function PositionRoundtablePage({
|
||||
setRightPanelOpen(true);
|
||||
}
|
||||
const next = new URLSearchParams(searchParams);
|
||||
next.set("taskId", task.id);
|
||||
if (taskScopeId) next.set("taskId", taskScopeId);
|
||||
else next.delete("taskId");
|
||||
next.set("sessionId", session.id);
|
||||
next.delete("new");
|
||||
setSearchParams(next, { replace: true });
|
||||
@@ -2083,6 +2113,7 @@ export default function PositionRoundtablePage({
|
||||
setSearchParams,
|
||||
startingChain,
|
||||
task,
|
||||
taskScopeId,
|
||||
intentPositionId,
|
||||
positionId,
|
||||
]);
|
||||
@@ -2124,12 +2155,13 @@ export default function PositionRoundtablePage({
|
||||
setBuiltinAutoStartRequestKey(0);
|
||||
setIntentCompletedAt("");
|
||||
const next = new URLSearchParams(searchParams);
|
||||
next.set("taskId", task.id);
|
||||
if (taskScopeId) next.set("taskId", taskScopeId);
|
||||
else next.delete("taskId");
|
||||
next.set("positionId", intentPositionId);
|
||||
next.delete("sessionId");
|
||||
next.set("new", "1");
|
||||
setSearchParams(next);
|
||||
}, [intent, intentPositionId, queueIntentConversationSave, searchParams, setSearchParams, task.id]);
|
||||
}, [intent, intentPositionId, queueIntentConversationSave, searchParams, setSearchParams, taskScopeId]);
|
||||
|
||||
const loadHistorySessions = useCallback(() => {
|
||||
if (isLocalPositionDemoSession(positionSessionRef.current?.id)) {
|
||||
@@ -2138,7 +2170,7 @@ export default function PositionRoundtablePage({
|
||||
return;
|
||||
}
|
||||
setHistoryLoading(true);
|
||||
void listPositionSessions(task.id)
|
||||
void listPositionSessions(taskScopeId ?? undefined)
|
||||
.then((sessions) => {
|
||||
setHistorySessions(
|
||||
[...sessions].sort((left, right) => {
|
||||
@@ -2154,7 +2186,7 @@ export default function PositionRoundtablePage({
|
||||
.finally(() => {
|
||||
setHistoryLoading(false);
|
||||
});
|
||||
}, [task.id]);
|
||||
}, [taskScopeId]);
|
||||
|
||||
const handleHistoryMenuOpenChange = useCallback(
|
||||
(open: boolean) => {
|
||||
@@ -2198,7 +2230,8 @@ export default function PositionRoundtablePage({
|
||||
restoringIntentSessionRef.current = null;
|
||||
persistedIntentRef.current = null;
|
||||
const next = new URLSearchParams(searchParams);
|
||||
next.set("taskId", task.id);
|
||||
if (taskScopeId) next.set("taskId", taskScopeId);
|
||||
else next.delete("taskId");
|
||||
next.set("sessionId", sessionId);
|
||||
next.delete("new");
|
||||
setSearchParams(next);
|
||||
@@ -2209,7 +2242,7 @@ export default function PositionRoundtablePage({
|
||||
searchParams,
|
||||
sessionIdFromUrl,
|
||||
setSearchParams,
|
||||
task.id,
|
||||
taskScopeId,
|
||||
],
|
||||
);
|
||||
|
||||
@@ -2269,7 +2302,8 @@ export default function PositionRoundtablePage({
|
||||
setSelectedAgentId(null);
|
||||
setHistoryMenuOpen(false);
|
||||
const next = new URLSearchParams(searchParams);
|
||||
next.set("taskId", task.id);
|
||||
if (taskScopeId) next.set("taskId", taskScopeId);
|
||||
else next.delete("taskId");
|
||||
if (nextSession) {
|
||||
// Prefer the most recently active remaining conversation so the
|
||||
// user stays in history instead of being dropped onto a blank page.
|
||||
@@ -2299,7 +2333,7 @@ export default function PositionRoundtablePage({
|
||||
sessionIdFromUrl,
|
||||
setSearchParams,
|
||||
standaloneDemoMode,
|
||||
task.id,
|
||||
taskScopeId,
|
||||
],
|
||||
);
|
||||
|
||||
|
||||
Reference in new issue
Block a user