chore: rebuild release package

This commit is contained in:
shiyue
2026-07-15 15:00:58 +08:00
parent 141a266f34
commit 614e222f14
11 changed files with 631 additions and 52 deletions

View File

@@ -174,6 +174,9 @@
let activeToolCalls = new Map();
let activeTodoCallTargets = new Map();
let closedCollabAgentIds = new Set();
let collabAgentStateCache = new Map();
let collabAgentIdsByToolUseId = new Map();
let closedCollabAgentIdsByToolUseId = new Map();
let toolDomSeq = 0;
let toolGroupCount = 0; // 当前 .msg-tools 直接子节点数(含已有父目录)
let hasGrouped = false; // 本次输出是否已触发过折叠
@@ -3721,10 +3724,6 @@
async function handleSelectedImageFiles(fileList) {
const files = Array.from(fileList || []).filter((file) => file && /^image\//.test(file.type || ''));
if (!files.length) return;
if (pendingAttachments.length + files.length > 4) {
appendError('单条消息最多附带 4 张图片。');
return;
}
const batch = files.map((file, index) => ({
id: `${Date.now()}-${index}-${Math.random().toString(36).slice(2, 8)}`,
filename: file.name || 'image',
@@ -4199,6 +4198,9 @@
activeToolCalls.clear();
activeTodoCallTargets.clear();
closedCollabAgentIds = new Set();
collabAgentStateCache = new Map();
collabAgentIdsByToolUseId = new Map();
closedCollabAgentIdsByToolUseId = new Map();
updateGenerationControls();
chatTitle.textContent = '新会话';
updateSessionIdBadge();
@@ -6625,7 +6627,7 @@
const role = cleanCollabAgentText(state.role || state.agent || state.agentType || '');
let status = cleanCollabAgentText(state.status || state.state || 'pending') || 'pending';
if (state.closedAt && collabStateTone(status) !== 'closed') status = 'closed';
const detail = cleanCollabAgentText(state.candidateResult || state.finalMessage || state.result || state.output || state.summary || state.message || state.lastMessage || state.step || state.description || '');
const detail = cleanCollabAgentText(state.detail || state.candidateResult || state.finalMessage || state.result || state.output || state.summary || state.message || state.lastMessage || state.step || state.description || '');
return {
id,
label,
@@ -6715,6 +6717,124 @@
getClosedCollabAgentIdsFromTool(tool).forEach((id) => closedCollabAgentIds.add(id));
}
function normalizeCollabAgentThreadId(id) {
return cleanCollabAgentText(id);
}
function addCollabAgentIdsToMap(map, key, ids) {
const mapKey = cleanCollabAgentText(key);
const values = Array.isArray(ids) || ids instanceof Set ? Array.from(ids) : [ids];
const normalizedIds = values.map(normalizeCollabAgentThreadId).filter(Boolean);
if (!mapKey || normalizedIds.length === 0) return;
const set = map.get(mapKey) || new Set();
normalizedIds.forEach((id) => set.add(id));
map.set(mapKey, set);
}
function rememberCollabAgentIdsForTool(toolUseId, ids) {
addCollabAgentIdsToMap(collabAgentIdsByToolUseId, toolUseId, ids);
}
function rememberClosedCollabAgentIdsForTool(toolUseId, ids) {
addCollabAgentIdsToMap(closedCollabAgentIdsByToolUseId, toolUseId, ids);
}
function collectScopedCollabAgentIdsForToolMap(map) {
const ids = new Set();
if (!(map instanceof Map)) return ids;
map.forEach((tool, key) => {
getCollabAgentIdsFromTool(tool).forEach((id) => ids.add(id));
[key, tool?.id].forEach((toolKey) => {
const normalizedKey = cleanCollabAgentText(toolKey);
if (!normalizedKey) return;
const cachedIds = collabAgentIdsByToolUseId.get(normalizedKey);
if (cachedIds instanceof Set) cachedIds.forEach((id) => ids.add(id));
});
});
return ids;
}
function collectScopedClosedCollabAgentIdsForToolMap(map) {
const ids = new Set();
if (!(map instanceof Map)) return ids;
map.forEach((tool, key) => {
getClosedCollabAgentIdsFromTool(tool).forEach((id) => ids.add(id));
[key, tool?.id].forEach((toolKey) => {
const normalizedKey = cleanCollabAgentText(toolKey);
if (!normalizedKey) return;
const cachedIds = closedCollabAgentIdsByToolUseId.get(normalizedKey);
if (cachedIds instanceof Set) cachedIds.forEach((id) => ids.add(id));
});
});
return ids;
}
function rememberCollabAgentState(id, incomingState = {}, fallbackPrompt = '', index = 0) {
const threadId = normalizeCollabAgentThreadId(id);
if (!threadId) return null;
const state = incomingState && typeof incomingState === 'object' ? incomingState : { status: incomingState };
const previousState = collabAgentStateCache.get(threadId) || {};
const nextState = mergeCollabAgentTaskState(previousState, state, fallbackPrompt, threadId, index);
const status = cleanCollabAgentText(state.status || state.state || nextState.status || previousState.status || '');
const detail = cleanCollabAgentText(
state.detail
|| state.candidateResult
|| state.finalMessage
|| state.result
|| state.output
|| state.summary
|| state.message
|| state.lastMessage
|| state.step
|| state.description
|| nextState.detail
|| previousState.detail
|| ''
);
const role = cleanCollabAgentText(state.role || state.agent || state.agentType || nextState.role || previousState.role || '');
const cachedState = { ...nextState };
if (status) cachedState.status = status;
if (detail) cachedState.detail = detail;
if (role) cachedState.role = role;
if (state.candidateResult !== undefined) cachedState.candidateResult = state.candidateResult;
if (state.finalMessage !== undefined) cachedState.finalMessage = state.finalMessage;
if (state.closedAt !== undefined) cachedState.closedAt = state.closedAt;
if (state.returnedAt !== undefined) cachedState.returnedAt = state.returnedAt;
collabAgentStateCache.set(threadId, cachedState);
return cachedState;
}
function rememberCollabAgentStateFromChild(child, toolUseId = '') {
if (!child || typeof child !== 'object') return '';
const threadId = normalizeCollabAgentThreadId(
child.threadId
|| child.thread_id
|| child.agentId
|| child.agent_id
|| child.id
);
if (!threadId) return '';
const incomingState = {
...child,
label: child.label || child.title || child.nickname || child.name || '',
name: child.name || child.label || threadId,
role: child.role || child.agent || child.agentType || '',
status: child.status || child.state || 'running',
taskDescription: collabAgentTaskDescription(child),
candidateResult: child.finalMessage || child.candidateResult || '',
finalMessage: child.finalMessage || '',
closedAt: child.closedAt || null,
returnedAt: child.returnedAt || null,
};
const cachedState = rememberCollabAgentState(threadId, incomingState, '', collabAgentStateCache.size);
rememberCollabAgentIdsForTool(toolUseId, [threadId]);
if (collabStateTone(cachedState?.status || child.status) === 'closed') {
closedCollabAgentIds.add(threadId);
rememberClosedCollabAgentIdsForTool(toolUseId, [threadId]);
}
return threadId;
}
function mergeCollabAgentTools(tools, options = {}) {
const list = Array.isArray(tools) ? tools.filter((tool) => toolKind(tool) === 'collab_agent_tool_call') : [];
if (list.length === 0) return null;
@@ -6722,20 +6842,28 @@
const receiverThreadIds = [];
const knownClosedIds = options.closedAgentIds instanceof Set ? options.closedAgentIds : closedCollabAgentIds;
const localClosedIds = new Set(knownClosedIds || []);
const scopedRestoreIds = options.restoreAgentIds instanceof Set ? options.restoreAgentIds : new Set();
const scopedClosedIds = options.closedAgentIds instanceof Set ? options.closedAgentIds : new Set();
let toolName = '子代';
let prompt = '';
let status = '';
let done = false;
let hasCloseAction = false;
list.forEach((tool, toolIndex) => {
list.forEach((tool) => {
const data = normalizeCollabAgentData(tool);
const action = getCollabAgentAction(tool, data);
const isCloseAction = action === 'close_agent';
if (isCloseAction) hasCloseAction = true;
const displayAction = String(data.tool || tool.name || '').trim();
if (displayAction && !['wait_agent', 'close_agent'].includes(action)) toolName = displayAction;
if (!prompt && data.prompt) prompt = data.prompt;
const toolAgentIds = getCollabAgentIdsFromTool(tool);
const toolClosedIds = getClosedCollabAgentIdsFromTool(tool);
rememberCollabAgentIdsForTool(tool.id, toolAgentIds);
rememberClosedCollabAgentIdsForTool(tool.id, toolClosedIds);
if (isCloseAction) {
getCollabAgentIdsFromTool(tool).forEach((id) => localClosedIds.add(id));
toolAgentIds.forEach((id) => localClosedIds.add(id));
}
const dataStatus = isCloseAction ? 'closed' : data.status;
if (dataStatus) status = dataStatus;
@@ -6750,14 +6878,23 @@
entry.id,
receiverThreadIds.indexOf(entry.id)
);
states[entry.id] = {
const nextStatus = isCloseAction || localClosedIds.has(entry.id) ? 'closed' : entry.status;
states[entry.id] = rememberCollabAgentState(
entry.id,
{
...nextState,
status: nextStatus,
},
data.prompt,
receiverThreadIds.indexOf(entry.id)
) || {
...nextState,
status: isCloseAction || localClosedIds.has(entry.id) ? 'closed' : entry.status,
status: nextStatus,
};
if (collabStateTone(states[entry.id].status) === 'closed') localClosedIds.add(entry.id);
});
getCollabAgentIdsFromTool(tool).forEach((id) => {
toolAgentIds.forEach((id) => {
if (!receiverThreadIds.includes(id)) receiverThreadIds.push(id);
const nextState = mergeCollabAgentTaskState(
states[id],
@@ -6766,28 +6903,77 @@
id,
receiverThreadIds.indexOf(id)
);
states[id] = {
const nextStatus = isCloseAction || localClosedIds.has(id)
? 'closed'
: (data.status || states[id]?.status || (tool.done ? 'completed' : 'running'));
states[id] = rememberCollabAgentState(
id,
{
...nextState,
status: nextStatus,
},
data.prompt,
receiverThreadIds.indexOf(id)
) || {
...nextState,
status: isCloseAction || localClosedIds.has(id)
? 'closed'
: (data.status || states[id]?.status || (tool.done ? 'completed' : 'running')),
status: nextStatus,
};
});
if (receiverThreadIds.length === 0 && list.length === 1) {
const fallbackId = tool.id || `tool-${toolIndex + 1}`;
receiverThreadIds.push(fallbackId);
states[fallbackId] = {
...mergeCollabAgentTaskState({}, { label: '子代理' }, data.prompt, fallbackId, toolIndex),
status: isCloseAction ? 'closed' : (data.status || (tool.done ? 'completed' : 'running')),
};
}
});
const recoverSourceIds = hasCloseAction
? Array.from(scopedClosedIds)
: Array.from(new Set([...scopedRestoreIds, ...scopedClosedIds]));
recoverSourceIds.forEach((id) => {
const threadId = normalizeCollabAgentThreadId(id);
if (!threadId || receiverThreadIds.includes(threadId)) return;
const cachedState = collabAgentStateCache.get(threadId);
if (!cachedState) return;
receiverThreadIds.push(threadId);
const index = receiverThreadIds.indexOf(threadId);
const nextStatus = localClosedIds.has(threadId)
? 'closed'
: (cachedState.status || (done ? 'completed' : 'running'));
states[threadId] = rememberCollabAgentState(
threadId,
{
...cachedState,
status: nextStatus,
},
'',
index
) || {
...mergeCollabAgentTaskState(cachedState, { status: nextStatus }, '', threadId, index),
status: nextStatus,
};
});
if (receiverThreadIds.length === 0 && list.length === 1) {
const tool = list[0];
const data = normalizeCollabAgentData(tool);
const action = getCollabAgentAction(tool, data);
const isCloseAction = action === 'close_agent';
const fallbackId = tool.id || 'tool-1';
receiverThreadIds.push(fallbackId);
states[fallbackId] = {
...mergeCollabAgentTaskState({}, { label: '子代理' }, data.prompt, fallbackId, 0),
status: isCloseAction ? 'closed' : (data.status || (tool.done ? 'completed' : 'running')),
};
}
receiverThreadIds.forEach((id, index) => {
states[id] = {
const nextStatus = localClosedIds.has(id) ? 'closed' : (states[id]?.status || 'pending');
states[id] = rememberCollabAgentState(
id,
{
...states[id],
status: nextStatus,
},
'',
index
) || {
...mergeCollabAgentTaskState(states[id], {}, '', id, index),
status: localClosedIds.has(id) ? 'closed' : (states[id]?.status || 'pending'),
status: nextStatus,
};
});
@@ -7089,6 +7275,9 @@
const epoch = renderEpoch;
const baseIndex = Number.isFinite(Number(options.baseIndex)) ? Number(options.baseIndex) : 0;
closedCollabAgentIds = collectClosedCollabAgentIds(messages);
collabAgentStateCache = new Map();
collabAgentIdsByToolUseId = new Map();
closedCollabAgentIdsByToolUseId = new Map();
messagesDiv.innerHTML = '';
clearUserMessageIndex();
if (messages.length === 0) {
@@ -7455,7 +7644,12 @@
rememberClosedCollabAgentIdsFromTool(nextTool);
const map = existing?.__collabTools instanceof Map ? existing.__collabTools : new Map();
map.set(toolUseId || nextTool.id || `collab-${map.size + 1}`, nextTool);
const merged = mergeCollabAgentTools(Array.from(map.values()));
const restoreAgentIds = collectScopedCollabAgentIdsForToolMap(map);
const closedAgentIds = collectScopedClosedCollabAgentIdsForToolMap(map);
const mergeOptions = {};
if (restoreAgentIds.size > 0) mergeOptions.restoreAgentIds = restoreAgentIds;
if (closedAgentIds.size > 0) mergeOptions.closedAgentIds = closedAgentIds;
const merged = mergeCollabAgentTools(Array.from(map.values()), mergeOptions);
if (!merged) return existing;
if (existing) {
@@ -7643,10 +7837,12 @@
const tool = msg?.tool;
const toolUseId = msg?.toolUseId || tool?.id;
if (!toolUseId || !tool) return;
if (toolKind(tool) !== 'collab_agent_tool_call') return;
const isCurrentSessionUpdate = msg.sessionId === currentSessionId;
if (isCurrentSessionUpdate) {
const childThreadId = rememberCollabAgentStateFromChild(msg.child, toolUseId);
if (msg?.child?.threadId && collabStateTone(msg.child.status) === 'closed') {
closedCollabAgentIds.add(String(msg.child.threadId));
closedCollabAgentIds.add(String(childThreadId || msg.child.threadId));
}
rememberClosedCollabAgentIdsFromTool(tool);
}