From 6d1a0b6c86614121ad3ec4cc757e5665190d90c1 Mon Sep 17 00:00:00 2001 From: dal Date: Mon, 18 Aug 2025 10:31:52 -0600 Subject: [PATCH] todos cleanedup --- packages/ai/src/llm/ai-fallback.ts | 8 ++-- .../create-todos-step-finish.ts | 6 +-- .../create-todos-step-start.ts | 6 +-- .../create-todos-step/create-todos-step.ts | 8 ---- .../helpers/create-todos-transform-helper.ts | 39 +++++++++++++++---- 5 files changed, 41 insertions(+), 26 deletions(-) diff --git a/packages/ai/src/llm/ai-fallback.ts b/packages/ai/src/llm/ai-fallback.ts index f73b980cf..17c248e04 100644 --- a/packages/ai/src/llm/ai-fallback.ts +++ b/packages/ai/src/llm/ai-fallback.ts @@ -257,18 +257,18 @@ export class FallbackModel implements LanguageModelV2 { } catch (error) { // Check if this is a normal stream termination const errorMessage = error instanceof Error ? error.message : String(error); - const isNormalTermination = - errorMessage === 'terminated' || + const isNormalTermination = + errorMessage === 'terminated' || errorMessage.includes('terminated') || errorMessage === 'aborted' || errorMessage.includes('aborted'); - + // If it's a normal termination and we've already streamed content, just close normally if (isNormalTermination && hasStreamedAny) { controller.close(); return; } - + if (self.settings.onError) { try { await self.settings.onError(error as RetryableError, self.modelId); diff --git a/packages/ai/src/steps/analyst-agent-steps/create-todos-step/create-todos-step-finish.ts b/packages/ai/src/steps/analyst-agent-steps/create-todos-step/create-todos-step-finish.ts index 3a985cd3f..c3140e583 100644 --- a/packages/ai/src/steps/analyst-agent-steps/create-todos-step/create-todos-step-finish.ts +++ b/packages/ai/src/steps/analyst-agent-steps/create-todos-step/create-todos-step-finish.ts @@ -17,14 +17,14 @@ export function createTodosStepFinish(todosState: CreateTodosState, context: Cre // Create final reasoning message with completed status const todosReasoningEntry = createTodosReasoningMessage(todosState); - const todosRawMessage = createTodosRawLlmMessageEntry(todosState); + const todosRawMessages = createTodosRawLlmMessageEntry(todosState); try { - if (todosReasoningEntry && todosRawMessage) { + if (todosReasoningEntry && todosRawMessages) { await updateMessageEntries({ messageId: context.messageId, reasoningMessages: [todosReasoningEntry], - rawLlmMessages: [todosRawMessage], + rawLlmMessages: todosRawMessages, }); } } catch (error) { diff --git a/packages/ai/src/steps/analyst-agent-steps/create-todos-step/create-todos-step-start.ts b/packages/ai/src/steps/analyst-agent-steps/create-todos-step/create-todos-step-start.ts index af4f7dbba..5fc0b6944 100644 --- a/packages/ai/src/steps/analyst-agent-steps/create-todos-step/create-todos-step-start.ts +++ b/packages/ai/src/steps/analyst-agent-steps/create-todos-step/create-todos-step-start.ts @@ -18,14 +18,14 @@ export function createTodosStepStart(todosState: CreateTodosState, context: Crea // Create initial reasoning message with loading status const todosReasoningEntry = createTodosReasoningMessage(todosState, toolCallId); - const todosRawMessage = createTodosRawLlmMessageEntry(todosState, toolCallId); + const todosRawMessages = createTodosRawLlmMessageEntry(todosState, toolCallId); try { - if (todosReasoningEntry && todosRawMessage) { + if (todosReasoningEntry && todosRawMessages) { await updateMessageEntries({ messageId: context.messageId, reasoningMessages: [todosReasoningEntry], - rawLlmMessages: [todosRawMessage], + rawLlmMessages: todosRawMessages, }); } } catch (error) { diff --git a/packages/ai/src/steps/analyst-agent-steps/create-todos-step/create-todos-step.ts b/packages/ai/src/steps/analyst-agent-steps/create-todos-step/create-todos-step.ts index 58211704a..d40ac161b 100644 --- a/packages/ai/src/steps/analyst-agent-steps/create-todos-step/create-todos-step.ts +++ b/packages/ai/src/steps/analyst-agent-steps/create-todos-step/create-todos-step.ts @@ -171,14 +171,6 @@ export async function runCreateTodosStep(params: CreateTodosParams): Promise\n- Below are the items on your TODO list:\n${todos}\n`, - }); - } - return { todos, messages: resultMessages, diff --git a/packages/ai/src/steps/analyst-agent-steps/create-todos-step/helpers/create-todos-transform-helper.ts b/packages/ai/src/steps/analyst-agent-steps/create-todos-step/helpers/create-todos-transform-helper.ts index f5be9d51c..8beab4e12 100644 --- a/packages/ai/src/steps/analyst-agent-steps/create-todos-step/helpers/create-todos-transform-helper.ts +++ b/packages/ai/src/steps/analyst-agent-steps/create-todos-step/helpers/create-todos-transform-helper.ts @@ -50,28 +50,51 @@ export function createTodosReasoningMessage( } /** - * Creates a raw LLM message entry for TODOs - * This is stored as a raw user message in the database + * Creates raw LLM message entries for TODOs as tool call and result + * This is stored as tool messages in the database to preserve the original user message */ export function createTodosRawLlmMessageEntry( todosState: CreateTodosState, toolCallId?: string -): ModelMessage | null { +): ModelMessage[] | null { const id = todosState.entry_id || toolCallId; if (!id || !todosState.todos) { return null; } - return { - role: 'user', + const messages: ModelMessage[] = []; + + // Add assistant message with tool call + messages.push({ + role: 'assistant', content: [ { - type: 'text', - text: `\n- Below are the items on your TODO list:\n${todosState.todos}\n`, + type: 'tool-call', + toolCallId: id, + toolName: 'createTodos', + input: {}, }, ], - }; + }); + + // Add tool result message + messages.push({ + role: 'tool', + content: [ + { + type: 'tool-result', + toolCallId: id, + toolName: 'createTodos', + output: { + type: 'text', + value: todosState.todos, + }, + }, + ], + }); + + return messages; } /**