diff --git a/src/apps/call/Telephone.tsx b/src/apps/call/Telephone.tsx index 7ca374001..08e9fa187 100644 --- a/src/apps/call/Telephone.tsx +++ b/src/apps/call/Telephone.tsx @@ -15,7 +15,7 @@ import { useChatLLMDropdown } from '../chat/components/layout-bar/useLLMDropdown import { SystemPurposeId, SystemPurposes } from '../../data'; import { elevenLabsSpeakText } from '~/modules/elevenlabs/elevenlabs.client'; -import { AixChatGenerateContent_DMessage, aixChatGenerateContent_DMessage_FromConversation } from '~/modules/aix/client/aix.client'; +import { AixChatGenerateContent_DMessageGuts, aixChatGenerateContent_DMessage_FromConversation } from '~/modules/aix/client/aix.client'; import { useElevenLabsVoiceDropdown } from '~/modules/elevenlabs/useElevenLabsVoiceDropdown'; import type { OptimaBarControlMethods } from '~/common/layout/optima/bar/OptimaBarDropdown'; @@ -254,7 +254,7 @@ export function Telephone(props: { 'call', callMessages[0].id, { abortSignal: responseAbortController.current.signal }, - (update: AixChatGenerateContent_DMessage, _isDone: boolean) => { + (update: AixChatGenerateContent_DMessageGuts, _isDone: boolean) => { const updatedText = messageFragmentsReduceText(update.fragments).trim(); if (updatedText) setPersonaTextInterim(finalText = updatedText); diff --git a/src/apps/chat/editors/chat-persona.ts b/src/apps/chat/editors/chat-persona.ts index 93b93f91b..38fdfb051 100644 --- a/src/apps/chat/editors/chat-persona.ts +++ b/src/apps/chat/editors/chat-persona.ts @@ -1,4 +1,4 @@ -import { AixChatGenerateContent_DMessage, aixChatGenerateContent_DMessage_FromConversation } from '~/modules/aix/client/aix.client'; +import { AixChatGenerateContent_DMessageGuts, aixChatGenerateContent_DMessage_FromConversation } from '~/modules/aix/client/aix.client'; import { autoChatFollowUps } from '~/modules/aifn/auto-chat-follow-ups/autoChatFollowUps'; import { autoConversationTitle } from '~/modules/aifn/autotitle/autoTitle'; @@ -19,7 +19,7 @@ export const CHATGENERATE_RESPONSE_PLACEHOLDER = '...'; // 💫 ..., 🖊️ ... export interface PersonaProcessorInterface { - handleMessage(accumulatedMessage: AixChatGenerateContent_DMessage, messageComplete: boolean): void; + handleMessage(accumulatedMessage: AixChatGenerateContent_DMessageGuts, messageComplete: boolean): void; } @@ -72,7 +72,7 @@ export async function runPersonaOnConversationHead( 'conversation', conversationId, { abortSignal: abortController.signal, throttleParallelThreads: parallelViewCount }, - (messageOverwrite: AixChatGenerateContent_DMessage, messageComplete: boolean) => { + (messageOverwrite: AixChatGenerateContent_DMessageGuts, messageComplete: boolean) => { // Note: there was an abort check here, but it removed the last packet, which contained the cause and final text. // if (abortController.signal.aborted) diff --git a/src/apps/chat/editors/persona/PersonaChatMessageSpeak.ts b/src/apps/chat/editors/persona/PersonaChatMessageSpeak.ts index e51814686..8026ee757 100644 --- a/src/apps/chat/editors/persona/PersonaChatMessageSpeak.ts +++ b/src/apps/chat/editors/persona/PersonaChatMessageSpeak.ts @@ -2,7 +2,7 @@ import { elevenLabsSpeakText } from '~/modules/elevenlabs/elevenlabs.client'; import { isTextContentFragment } from '~/common/stores/chat/chat.fragments'; -import type { AixChatGenerateContent_DMessage } from '~/modules/aix/client/aix.client'; +import type { AixChatGenerateContent_DMessageGuts } from '~/modules/aix/client/aix.client'; import type { PersonaProcessorInterface } from '../chat-persona'; @@ -16,7 +16,7 @@ export class PersonaChatMessageSpeak implements PersonaProcessorInterface { constructor(private autoSpeakType: AutoSpeakType) { } - handleMessage(accumulatedMessage: Partial, messageComplete: boolean) { + handleMessage(accumulatedMessage: Partial, messageComplete: boolean) { if (this.autoSpeakType === 'off' || this.spokenLine) return; // Require a Content.Text first fragment diff --git a/src/modules/aix/client/aix.client.ts b/src/modules/aix/client/aix.client.ts index ebbfbb597..a728b2bbf 100644 --- a/src/modules/aix/client/aix.client.ts +++ b/src/modules/aix/client/aix.client.ts @@ -131,8 +131,8 @@ export function aixCreateModelFromLLMOptions( * Accumulator for ChatGenerate output data, as it is being streamed. * The object is modified in-place from the lower layers and passed to the callback for efficiency. */ -export interface AixChatGenerateContent_DMessage extends Pick { - fragments: (DMessageContentFragment | DMessageVoidFragment)[]; +export interface AixChatGenerateContent_DMessageGuts extends Pick { + fragments: (DMessageContentFragment | DMessageVoidFragment /* no AttachmentFragments */)[]; // Since 'aixChatGenerateContent_DMessage_FromConversation' starts from named (before replacement from LL), we can't Extract generator: DMessageGenerator; // Extract; pendingIncomplete: boolean; @@ -140,7 +140,7 @@ export interface AixChatGenerateContent_DMessage extends Pick MaybePromise, + onStreamingUpdate: (update: AixChatGenerateContent_DMessageGuts, isDone: boolean) => MaybePromise, ): Promise { let errorMessage: string | undefined; - let lastDMessage: AixChatGenerateContent_DMessage = { + let lastDMessage: AixChatGenerateContent_DMessageGuts = { fragments: [], generator: { mgt: 'named', @@ -196,7 +196,7 @@ export async function aixChatGenerateContent_DMessage_FromConversation( aixCreateChatGenerateContext(aixContextName, aixContextRef), true, clientOptions, - async (update: AixChatGenerateContent_DMessage, isDone: boolean) => { + async (update: AixChatGenerateContent_DMessageGuts, isDone: boolean) => { lastDMessage = update; await onStreamingUpdate(lastDMessage, isDone); }, @@ -207,13 +207,14 @@ export async function aixChatGenerateContent_DMessage_FromConversation( // this can only be a large, user-visible error, such as LLM not found console.warn('[DEV] aixChatGenerateContentStreaming error:', { error }); + // > error fragment errorMessage = error.message || (typeof error === 'string' ? error : 'Chat stopped.'); lastDMessage.fragments.push(createErrorContentFragment(`Issue: ${errorMessage}`)); - lastDMessage.generator = { - ...lastDMessage.generator, - tokenStopReason: 'issue', - }; + + // .generator: 'issue', no pendingIncomplete + lastDMessage.generator = { ...lastDMessage.generator, tokenStopReason: 'issue' }; lastDMessage.pendingIncomplete = false; + } // TODO: check something beyond this return status (as exceptions almost never happen here) @@ -371,7 +372,7 @@ export async function aixChatGenerateText_Simple( */ function _llToText(src: AixChatGenerateContent_LL, dest: AixChatGenerateText_Simple) { // copy over just the generator by using the accumulator -> DMessage-like copier - _llToDMessage(src, { + _llToDMessageGuts(src, { generator: dest.generator, // target our dest's object fragments: [], pendingIncomplete: false, // unused, mocked }); @@ -430,7 +431,7 @@ function _llToText(src: AixChatGenerateContent_LL, dest: AixChatGenerateText_Sim * @param clientOptions - Client options for the operation * @param onStreamingUpdate - Optional callback for streaming updates * - * @returns Promise - The final DMessage-compatible object + * @returns Promise - The final DMessage-compatible object */ export async function aixChatGenerateContent_DMessage( // llm Id input -> access & model @@ -441,8 +442,8 @@ export async function aixChatGenerateContent_DMessage MaybePromise, -): Promise { + onStreamingUpdate?: (update: AixChatGenerateContent_DMessageGuts, isDone: boolean) => MaybePromise, +): Promise { // Aix Access const llm = findLLMOrThrow(llmId); @@ -466,7 +467,7 @@ export async function aixChatGenerateContent_DMessage { if (isDone) return; // optimization, as there aren't branches between here and the final update below if (onStreamingUpdate) { - _llToDMessage(ll, dMessage); + _llToDMessageGuts(ll, dMessage); await onStreamingUpdate(dMessage, false); } }, @@ -509,7 +510,7 @@ export async function aixChatGenerateContent_DMessage { + const onMessageUpdated = (update: AixChatGenerateContent_DMessageGuts, completed: boolean) => { // in-place update of the intermediate message const { fragments: incrementalFragments, ...incrementalRest } = update; Object.assign(inputs.intermediateDMessage, incrementalRest); diff --git a/src/modules/beam/scatter/beam.scatter.ts b/src/modules/beam/scatter/beam.scatter.ts index 0975aa718..7fbb745df 100644 --- a/src/modules/beam/scatter/beam.scatter.ts +++ b/src/modules/beam/scatter/beam.scatter.ts @@ -1,6 +1,6 @@ import type { StateCreator } from 'zustand/vanilla'; -import { AixChatGenerateContent_DMessage, aixChatGenerateContent_DMessage_FromConversation } from '~/modules/aix/client/aix.client'; +import { AixChatGenerateContent_DMessageGuts, aixChatGenerateContent_DMessage_FromConversation } from '~/modules/aix/client/aix.client'; import type { DLLMId } from '~/common/stores/llms/llms.types'; import { agiUuid } from '~/common/util/idUtils'; @@ -60,7 +60,7 @@ function rayScatterStart(ray: BRay, llmId: DLLMId | null, inputHistory: DMessage const abortController = new AbortController(); - const onMessageUpdated = (incrementalMessage: AixChatGenerateContent_DMessage, completed: boolean) => { + const onMessageUpdated = (incrementalMessage: AixChatGenerateContent_DMessageGuts, completed: boolean) => { const { fragments: incrementalFragments, ...incrementalRest } = incrementalMessage; _rayUpdate(ray.rayId, (ray) => ({ message: {