From 82516e4fbbb45ad98cc09ae1440b656e2d5901cb Mon Sep 17 00:00:00 2001 From: dal Date: Thu, 14 Aug 2025 14:09:53 -0600 Subject: [PATCH] Update reasoning messages to improve clarity and consistency across tools - Changed the wording of elapsed time in reasoning messages from "min" to "minutes" for better readability. - Updated the final reasoning message format to specify "Reasoned for" instead of "Total workflow time," enhancing user understanding of the output. These changes contribute to a more user-friendly experience and maintain consistency in messaging across different tools. --- .../done-tool/done-tool-start.ts | 4 +- .../message-user-clarifying-question-start.ts | 4 +- .../respond-without-asset-creation-start.ts | 4 +- .../messages/update-message-entries.ts | 91 +++++++++++-------- 4 files changed, 59 insertions(+), 44 deletions(-) diff --git a/packages/ai/src/tools/communication-tools/done-tool/done-tool-start.ts b/packages/ai/src/tools/communication-tools/done-tool/done-tool-start.ts index 1968e2faf..8cc7bbec6 100644 --- a/packages/ai/src/tools/communication-tools/done-tool/done-tool-start.ts +++ b/packages/ai/src/tools/communication-tools/done-tool/done-tool-start.ts @@ -80,12 +80,12 @@ export function createDoneToolStart(doneToolState: DoneToolState, context: DoneT timeString = `${elapsedSeconds} seconds`; } else { const elapsedMinutes = Math.floor(elapsedSeconds / 60); - timeString = `${elapsedMinutes} min`; + timeString = `${elapsedMinutes} minutes`; } await updateMessage(context.messageId, { isCompleted: true, - finalReasoningMessage: `Total workflow time: ${timeString}`, + finalReasoningMessage: `Reasoned for ${timeString}`, }); } } catch (error) { diff --git a/packages/ai/src/tools/communication-tools/message-user-clarifying-question/message-user-clarifying-question-start.ts b/packages/ai/src/tools/communication-tools/message-user-clarifying-question/message-user-clarifying-question-start.ts index a504dec41..c255d65a3 100644 --- a/packages/ai/src/tools/communication-tools/message-user-clarifying-question/message-user-clarifying-question-start.ts +++ b/packages/ai/src/tools/communication-tools/message-user-clarifying-question/message-user-clarifying-question-start.ts @@ -49,12 +49,12 @@ export function createMessageUserClarifyingQuestionStart( timeString = `${elapsedSeconds} seconds`; } else { const elapsedMinutes = Math.floor(elapsedSeconds / 60); - timeString = `${elapsedMinutes} min`; + timeString = `${elapsedMinutes} minutes`; } await updateMessage(messageId, { isCompleted: true, - finalReasoningMessage: `Total workflow time: ${timeString}`, + finalReasoningMessage: `Reasoned for ${timeString}`, }); } catch (error) { console.error( diff --git a/packages/ai/src/tools/communication-tools/respond-without-asset-creation/respond-without-asset-creation-start.ts b/packages/ai/src/tools/communication-tools/respond-without-asset-creation/respond-without-asset-creation-start.ts index d2502059c..c7061ab08 100644 --- a/packages/ai/src/tools/communication-tools/respond-without-asset-creation/respond-without-asset-creation-start.ts +++ b/packages/ai/src/tools/communication-tools/respond-without-asset-creation/respond-without-asset-creation-start.ts @@ -48,12 +48,12 @@ export function createRespondWithoutAssetCreationStart< timeString = `${elapsedSeconds} seconds`; } else { const elapsedMinutes = Math.floor(elapsedSeconds / 60); - timeString = `${elapsedMinutes} min`; + timeString = `${elapsedMinutes} minutes`; } await updateMessage(context.messageId, { isCompleted: true, - finalReasoningMessage: `Total workflow time: ${timeString}`, + finalReasoningMessage: `Reasoned for ${timeString}`, }); } catch (error) { console.error('[respond-without-asset-creation] Failed to update initial entries:', error); diff --git a/packages/database/src/queries/messages/update-message-entries.ts b/packages/database/src/queries/messages/update-message-entries.ts index e72fb308a..bfa8b2db1 100644 --- a/packages/database/src/queries/messages/update-message-entries.ts +++ b/packages/database/src/queries/messages/update-message-entries.ts @@ -30,23 +30,27 @@ export async function updateMessageEntries({ reasoningMessages, }: UpdateMessageEntriesParams): Promise<{ success: boolean }> { try { - const updates: Record = { updatedAt: new Date() }; + const updates: Record = { updatedAt: new Date().toISOString() }; // Optimized merge for response messages - upsert by 'id' if (responseMessages?.length) { const newData = JSON.stringify(responseMessages); updates.responseMessages = sql` COALESCE( - (SELECT jsonb_agg(value) + (SELECT jsonb_agg(value ORDER BY ordinality) FROM ( - SELECT DISTINCT ON (value->>'id') value - FROM ( - SELECT jsonb_array_elements(COALESCE(${messages.responseMessages}, '[]'::jsonb)) - UNION ALL - SELECT jsonb_array_elements(${newData}::jsonb) - ) combined(value) - ORDER BY value->>'id', value DESC - ) deduplicated), + -- Keep existing messages that aren't being updated + SELECT value, ordinality + FROM jsonb_array_elements(COALESCE(${messages.responseMessages}, '[]'::jsonb)) WITH ORDINALITY AS t(value, ordinality) + WHERE NOT EXISTS ( + SELECT 1 FROM jsonb_array_elements(${newData}::jsonb) AS new_msg + WHERE new_msg->>'id' = t.value->>'id' + ) + UNION ALL + -- Add new/updated messages at the end + SELECT value, 1000000 + ordinality AS ordinality + FROM jsonb_array_elements(${newData}::jsonb) WITH ORDINALITY AS t(value, ordinality) + ) combined), '[]'::jsonb )`; } @@ -56,16 +60,20 @@ export async function updateMessageEntries({ const newData = JSON.stringify(reasoningMessages); updates.reasoning = sql` COALESCE( - (SELECT jsonb_agg(value) + (SELECT jsonb_agg(value ORDER BY ordinality) FROM ( - SELECT DISTINCT ON (value->>'id') value - FROM ( - SELECT jsonb_array_elements(COALESCE(${messages.reasoning}, '[]'::jsonb)) - UNION ALL - SELECT jsonb_array_elements(${newData}::jsonb) - ) combined(value) - ORDER BY value->>'id', value DESC - ) deduplicated), + -- Keep existing messages that aren't being updated + SELECT value, ordinality + FROM jsonb_array_elements(COALESCE(${messages.reasoning}, '[]'::jsonb)) WITH ORDINALITY AS t(value, ordinality) + WHERE NOT EXISTS ( + SELECT 1 FROM jsonb_array_elements(${newData}::jsonb) AS new_msg + WHERE new_msg->>'id' = t.value->>'id' + ) + UNION ALL + -- Add new/updated messages at the end + SELECT value, 1000000 + ordinality AS ordinality + FROM jsonb_array_elements(${newData}::jsonb) WITH ORDINALITY AS t(value, ordinality) + ) combined), '[]'::jsonb )`; } @@ -75,26 +83,33 @@ export async function updateMessageEntries({ const newData = JSON.stringify(rawLlmMessages); updates.rawLlmMessages = sql` COALESCE( - (SELECT jsonb_agg(value) + (SELECT jsonb_agg(value ORDER BY ordinality) FROM ( - SELECT DISTINCT ON ( - value->>'role', - (SELECT string_agg(content->>'toolCallId', ',' ORDER BY content->>'toolCallId') - FROM jsonb_array_elements(value->'content') content - WHERE content->>'toolCallId' IS NOT NULL) - ) value - FROM ( - SELECT jsonb_array_elements(COALESCE(${messages.rawLlmMessages}, '[]'::jsonb)) - UNION ALL - SELECT jsonb_array_elements(${newData}::jsonb) - ) combined(value) - ORDER BY - value->>'role', - (SELECT string_agg(content->>'toolCallId', ',' ORDER BY content->>'toolCallId') - FROM jsonb_array_elements(value->'content') content - WHERE content->>'toolCallId' IS NOT NULL), - value DESC - ) deduplicated), + -- Keep existing messages that aren't being updated + SELECT value, ordinality + FROM jsonb_array_elements(COALESCE(${messages.rawLlmMessages}, '[]'::jsonb)) WITH ORDINALITY AS t(value, ordinality) + WHERE NOT EXISTS ( + SELECT 1 FROM jsonb_array_elements(${newData}::jsonb) AS new_msg + WHERE new_msg->>'role' = t.value->>'role' + AND ( + -- Compare toolCallIds if they exist + (SELECT string_agg(content->>'toolCallId', ',' ORDER BY content->>'toolCallId') + FROM jsonb_array_elements(new_msg->'content') content + WHERE content->>'toolCallId' IS NOT NULL) = + (SELECT string_agg(content->>'toolCallId', ',' ORDER BY content->>'toolCallId') + FROM jsonb_array_elements(t.value->'content') content + WHERE content->>'toolCallId' IS NOT NULL) + OR + -- Both have no toolCallIds + ((SELECT COUNT(*) FROM jsonb_array_elements(new_msg->'content') content WHERE content->>'toolCallId' IS NOT NULL) = 0 + AND (SELECT COUNT(*) FROM jsonb_array_elements(t.value->'content') content WHERE content->>'toolCallId' IS NOT NULL) = 0) + ) + ) + UNION ALL + -- Add new/updated messages at the end + SELECT value, 1000000 + ordinality AS ordinality + FROM jsonb_array_elements(${newData}::jsonb) WITH ORDINALITY AS t(value, ordinality) + ) combined), '[]'::jsonb )`; }