chore: rebuild release package

This commit is contained in:
shiyue
2026-07-16 18:04:37 +08:00
parent 614e222f14
commit 5c3401292d
18 changed files with 1032 additions and 64 deletions

View File

@@ -54,6 +54,12 @@
{ cmd: '/help', desc: '显示帮助' },
];
function isKnownSlashCommandText(text) {
const [command = ''] = String(text || '').trim().split(/\s+/, 1);
const normalized = command.toLowerCase();
return SLASH_COMMANDS.some((item) => item.cmd.toLowerCase() === normalized);
}
const MODE_LABELS = {
default: '默认',
plan: 'Plan',
@@ -5545,11 +5551,7 @@
pendingText = msg.text || '';
flushRender();
if (msg.toolCalls && msg.toolCalls.length > 0) {
const mergedCollabTool = mergeCollabAgentTools(msg.toolCalls);
const resumeToolCalls = [
...(mergedCollabTool ? [mergedCollabTool] : []),
...msg.toolCalls.filter((tc) => toolKind(tc) !== 'collab_agent_tool_call'),
];
const resumeToolCalls = renderToolCallsWithMergedCollab(msg.toolCalls);
for (const tc of resumeToolCalls) {
activeToolCalls.set(tc.id, {
name: tc.name,
@@ -6314,9 +6316,34 @@
let renderEpoch = 0;
function toolKind(tool) {
if (isSubAgentActivityTool(tool)) return 'collab_agent_tool_call';
return tool?.kind || tool?.meta?.kind || '';
}
function isSubAgentActivityTool(tool) {
const kind = String(tool?.kind || tool?.meta?.kind || tool?.type || '').trim();
const name = String(tool?.name || tool?.tool || '').trim();
const inputData = effectiveObject(tool?.input);
const resultData = effectiveObject(tool?.result);
const payload = {
...tool,
...inputData,
...resultData,
};
const inputType = String(inputData.type || '').trim();
const resultType = String(resultData.type || '').trim();
const activitySignal = inputData.kind || inputData.activityKind || inputData.activity_kind || inputData.status
|| resultData.kind || resultData.activityKind || resultData.activity_kind || resultData.status;
const hasActivitySignal = kind === 'subAgentActivity'
|| inputType === 'subAgentActivity'
|| resultType === 'subAgentActivity'
|| (
name === 'subAgentActivity'
&& !!activitySignal
);
return hasActivitySignal && !!getSubAgentActivityThreadId(payload);
}
function normalizeDisplayPath(filePath) {
const rawPath = typeof filePath === 'string' ? filePath.trim() : '';
if (!rawPath) return '';
@@ -6595,9 +6622,86 @@
return normalizeCollabAgentAction(value);
}
function collabAgentBasename(value) {
const text = cleanCollabAgentText(value).replace(/\\/g, '/');
if (!text) return '';
return text.split('/').filter(Boolean).pop() || text;
}
function normalizeSubAgentActivityStatus(value, done = false) {
const normalized = String(value || '').trim().toLowerCase().replace(/[\s_-]/g, '');
if (/^(started|interacted|interaction|message|delta|progress|updated|update)$/.test(normalized)) return 'running';
if (/^(returned|return)$/.test(normalized)) return 'returned';
if (/^(completed|complete|done|finished|finish|success|succeeded)$/.test(normalized)) return 'completed';
if (/^(closed|close|closing|stopped|stop)$/.test(normalized)) return 'closed';
if (/^(failed|fail|error|errored|cancelled|canceled|aborted|rejected)$/.test(normalized)) return 'failed';
return done ? 'completed' : 'running';
}
function getSubAgentActivityThreadId(activity = {}) {
return cleanCollabAgentText(
activity.agentThreadId
|| activity.agent_thread_id
|| activity.threadId
|| activity.thread_id
|| activity.childThreadId
|| activity.child_thread_id
|| ''
);
}
function normalizeSubAgentActivityData(tool, inputData, resultData) {
const activity = {
...inputData,
...resultData,
};
const threadId = getSubAgentActivityThreadId(activity);
if (!threadId) return null;
const activityKind = cleanCollabAgentText(activity.kind || activity.activityKind || activity.activity_kind || activity.status || '');
const agentTitle = collabAgentBasename(activity.agentPath || activity.agent_path || activity.agent || activity.role || activity.name || '');
const prompt = cleanCollabAgentText(activity.prompt || activity.taskDescription || activity.task_description || '');
const state = {
...activity,
label: agentTitle || activity.label || activity.title || activity.name || '',
title: agentTitle || activity.title || activity.label || activity.name || '',
name: agentTitle || activity.name || activity.label || activity.title || '',
role: cleanCollabAgentText(activity.role || activity.agentRole || activity.agent_role || ''),
status: normalizeSubAgentActivityStatus(activityKind, !!tool?.done),
activityKind,
agentPath: activity.agentPath || activity.agent_path || '',
hasReadableSourceTitle: !!agentTitle,
};
if (prompt) state.taskDescription = prompt;
return {
...activity,
type: 'subAgentActivity',
tool: 'subAgentActivity',
prompt,
status: state.status,
receiverThreadIds: [threadId],
agentsStates: {
[threadId]: state,
},
};
}
function aggregateCollabAgentStatus(receiverThreadIds, states, fallbackStatus = '', done = false) {
const ids = Array.isArray(receiverThreadIds) ? receiverThreadIds : [];
const tones = ids.map((id) => collabStateTone(states?.[id]?.status));
if (tones.length === 0) return fallbackStatus || (done ? 'completed' : 'running');
if (tones.some((tone) => tone === 'running')) return 'running';
if (tones.every((tone) => tone === 'closed')) return 'closed';
if (tones.some((tone) => tone === 'error')) return 'failed';
if (tones.every((tone) => tone === 'done' || tone === 'closed')) return 'completed';
if (tones.some((tone) => tone === 'pending')) return 'pending';
return fallbackStatus || (done ? 'completed' : 'running');
}
function normalizeCollabAgentData(tool) {
const inputData = effectiveObject(tool?.input);
const resultData = effectiveObject(tool?.result);
const activityData = isSubAgentActivityTool(tool) ? normalizeSubAgentActivityData(tool, inputData, resultData) : null;
if (activityData) return activityData;
const merged = {
...inputData,
...resultData,
@@ -6953,14 +7057,18 @@
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')),
};
if (!['wait_agent', 'close_agent'].includes(action)) {
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')),
};
}
}
if (receiverThreadIds.length === 0) return null;
receiverThreadIds.forEach((id, index) => {
const nextStatus = localClosedIds.has(id) ? 'closed' : (states[id]?.status || 'pending');
states[id] = rememberCollabAgentState(
@@ -6977,9 +7085,7 @@
};
});
const allClosed = receiverThreadIds.length > 0
&& receiverThreadIds.every((id) => collabStateTone(states[id]?.status) === 'closed');
const mergedStatus = allClosed ? 'closed' : (status || (done ? 'completed' : 'running'));
const mergedStatus = aggregateCollabAgentStatus(receiverThreadIds, states, status, done);
return {
id: list[0].id || 'collab-agent-merged',
@@ -6996,6 +7102,15 @@
};
}
function renderToolCallsWithMergedCollab(toolCalls, options = {}) {
const calls = Array.isArray(toolCalls) ? toolCalls : [];
const mergedCollabTool = mergeCollabAgentTools(calls, options);
return [
...(mergedCollabTool ? [mergedCollabTool] : []),
...calls.filter((tc) => toolKind(tc) !== 'collab_agent_tool_call'),
];
}
function collabStateTone(statusText) {
const normalized = String(statusText || '').toLowerCase();
if (!normalized) return 'pending';
@@ -7220,11 +7335,7 @@
const toolMount = bubble.querySelector(':scope > .cross-conversation-reply-body') || bubble;
const FOLD_AT = 3;
let grouped = false;
const mergedCollabTool = mergeCollabAgentTools(m.toolCalls);
const renderToolCalls = [
...(mergedCollabTool ? [mergedCollabTool] : []),
...m.toolCalls.filter((tc) => toolKind(tc) !== 'collab_agent_tool_call'),
];
const renderToolCalls = renderToolCallsWithMergedCollab(m.toolCalls);
for (const tc of renderToolCalls) {
if (isEmptyReasoningTool(tc)) continue;
const details = createToolCallElement(tc.id || `saved-${Math.random().toString(36).slice(2)}`, tc, true);
@@ -8403,17 +8514,9 @@
const cursor = typeof msgInput.selectionStart === 'number' ? msgInput.selectionStart : value.length;
const before = value.slice(0, cursor);
if (!before.includes('\n') && value.startsWith('/') && cursor > 0) {
const nextWhitespace = value.search(/\s/);
const end = nextWhitespace >= 0 ? Math.min(cursor, nextWhitespace) : cursor;
if (cursor <= end || nextWhitespace < 0) {
return { trigger: '/', query: value.slice(1, cursor), start: 0, end: cursor };
}
}
const lineStart = Math.max(before.lastIndexOf('\n'), before.lastIndexOf('\r')) + 1;
const line = before.slice(lineStart);
const match = line.match(/(^|\s)([@$])([^\s]*)$/);
const match = line.match(/(^|\s)([\/@$])([^\s]*)$/);
if (!match) return null;
const prefixLength = match[1] ? match[1].length : 0;
const start = lineStart + match.index + prefixLength;
@@ -8710,7 +8813,7 @@
appendError('Codex App 运行中插入暂不支持图片附件,请先移除图片。');
return;
}
if (text.startsWith('/')) {
if (isKnownSlashCommandText(text)) {
appendError('Codex App 运行中暂不支持 slash 指令插入。');
return;
}
@@ -8742,7 +8845,7 @@
}
// Slash commands: don't show as user bubble
if (text.startsWith('/')) {
if (isKnownSlashCommandText(text)) {
if (pendingAttachments.length > 0) {
appendError('命令消息暂不支持附带图片,请先移除图片或发送普通消息。');
return;