feat: improve conversation timeline and agent plans
This commit is contained in:
41
server.js
41
server.js
@@ -2903,18 +2903,32 @@ function normalizeTitleHistory(history) {
|
||||
const title = String(event.title || '').replace(/\s+/g, ' ').trim().slice(0, 120);
|
||||
const changedAtMs = Date.parse(String(event.changedAt || ''));
|
||||
const messageIndex = Number(event.messageIndex);
|
||||
const anchorMessageIndex = event.anchorMessageIndex;
|
||||
const source = String(event.source || '').trim().toLowerCase();
|
||||
if (!title || !Number.isFinite(changedAtMs) || !Number.isFinite(messageIndex) || messageIndex < 0 || source !== 'llm') return;
|
||||
normalized.push({
|
||||
const normalizedMessageIndex = Math.trunc(messageIndex);
|
||||
const normalizedEvent = {
|
||||
title,
|
||||
changedAt: new Date(changedAtMs).toISOString(),
|
||||
messageIndex: Math.trunc(messageIndex),
|
||||
messageIndex: normalizedMessageIndex,
|
||||
source: 'llm',
|
||||
});
|
||||
};
|
||||
if (Number.isInteger(anchorMessageIndex) && anchorMessageIndex >= 0 && anchorMessageIndex < normalizedMessageIndex) {
|
||||
normalizedEvent.anchorMessageIndex = anchorMessageIndex;
|
||||
}
|
||||
normalized.push(normalizedEvent);
|
||||
});
|
||||
return normalized.slice(-100);
|
||||
}
|
||||
|
||||
function findLatestUserMessageIndex(messages) {
|
||||
if (!Array.isArray(messages)) return null;
|
||||
for (let index = messages.length - 1; index >= 0; index -= 1) {
|
||||
if (messages[index]?.role === 'user') return index;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function normalizeSession(session) {
|
||||
if (!session || typeof session !== 'object') return session;
|
||||
session.agent = normalizeAgent(session.agent);
|
||||
@@ -7320,10 +7334,13 @@ function setCurrentConversationTitle(args = {}, sourceSessionId = '') {
|
||||
const changed = previousTitle !== normalizedTitle;
|
||||
let titleEvent = null;
|
||||
if (changed) {
|
||||
const messageIndex = Array.isArray(session.messages) ? session.messages.length : 0;
|
||||
const anchorMessageIndex = findLatestUserMessageIndex(session.messages);
|
||||
titleEvent = {
|
||||
title: normalizedTitle,
|
||||
changedAt: new Date().toISOString(),
|
||||
messageIndex: Array.isArray(session.messages) ? session.messages.length : 0,
|
||||
messageIndex,
|
||||
...(anchorMessageIndex !== null ? { anchorMessageIndex } : {}),
|
||||
source: 'llm',
|
||||
};
|
||||
session.titleHistory = normalizeTitleHistory([...(session.titleHistory || []), titleEvent]);
|
||||
@@ -8815,18 +8832,20 @@ function findLatestCcwebMcpCollabToolInToolCalls(toolCalls = []) {
|
||||
}
|
||||
|
||||
function findCcwebMcpChildTargetToolInToolCalls(toolCalls = [], spawnToolId = '') {
|
||||
return findExactCcwebMcpChildToolInToolCalls(toolCalls, spawnToolId)
|
||||
|| findLatestCcwebMcpCollabToolInToolCalls(toolCalls);
|
||||
const targetId = String(spawnToolId || '').trim();
|
||||
if (targetId) return findExactCcwebMcpChildToolInToolCalls(toolCalls, targetId);
|
||||
return findLatestCcwebMcpCollabToolInToolCalls(toolCalls);
|
||||
}
|
||||
|
||||
function findCcwebMcpChildTargetToolInMessages(messages = [], spawnToolId = '') {
|
||||
if (!Array.isArray(messages)) return null;
|
||||
const targetId = String(spawnToolId || '').trim();
|
||||
let latestCollabTool = null;
|
||||
for (let i = messages.length - 1; i >= 0; i -= 1) {
|
||||
const toolCalls = Array.isArray(messages[i]?.toolCalls) ? messages[i].toolCalls : [];
|
||||
const exactTool = findExactCcwebMcpChildToolInToolCalls(toolCalls, spawnToolId);
|
||||
const exactTool = findExactCcwebMcpChildToolInToolCalls(toolCalls, targetId);
|
||||
if (exactTool) return exactTool;
|
||||
if (!latestCollabTool) latestCollabTool = findLatestCcwebMcpCollabToolInToolCalls(toolCalls);
|
||||
if (!targetId && !latestCollabTool) latestCollabTool = findLatestCcwebMcpCollabToolInToolCalls(toolCalls);
|
||||
}
|
||||
return latestCollabTool;
|
||||
}
|
||||
@@ -8959,6 +8978,9 @@ function syncCcwebMcpChildAgentsFromCollabItem(routed, item = {}) {
|
||||
if (receiverThreadIds.length === 0) return;
|
||||
const activityAgentPath = String(item.agentPath || item.agent_path || '').trim();
|
||||
const activityPrompt = String(item.prompt || item.taskDescription || item.task_description || '').trim();
|
||||
const activityVisibleToolId = isSubAgentActivity
|
||||
? String((routed.role === 'child' ? routed.child?.spawnToolId : '') || item.id || '').trim()
|
||||
: '';
|
||||
const activityState = isSubAgentActivity ? {
|
||||
label: activityAgentPath ? path.basename(activityAgentPath) : '',
|
||||
role: String(item.role || item.agentRole || item.agent_role || '').trim(),
|
||||
@@ -8985,7 +9007,7 @@ function syncCcwebMcpChildAgentsFromCollabItem(routed, item = {}) {
|
||||
turnId: null,
|
||||
parentSessionId: routed.sessionId,
|
||||
parentThreadId,
|
||||
spawnToolId: isSpawn ? item.id : '',
|
||||
spawnToolId: isSpawn ? (activityVisibleToolId || item.id) : '',
|
||||
label: ccwebMcpChildLabel(state, threadId),
|
||||
role: String(state.role || state.agent || state.agentType || state.agent_type || '').trim(),
|
||||
agentPath: String(state.agentPath || state.agent_path || '').trim(),
|
||||
@@ -9001,6 +9023,7 @@ function syncCcwebMcpChildAgentsFromCollabItem(routed, item = {}) {
|
||||
createdAt: now,
|
||||
updatedAt: now,
|
||||
};
|
||||
if (isSubAgentActivity && activityVisibleToolId) child.spawnToolId = activityVisibleToolId;
|
||||
if (!child.spawnToolId && isSpawn) child.spawnToolId = item.id;
|
||||
if (!child.spawnToolId && item.id) child.spawnToolId = item.id;
|
||||
child.parentSessionId = child.parentSessionId || routed.sessionId;
|
||||
|
||||
Reference in New Issue
Block a user