mirror of
https://github.com/stackblitz-labs/bolt.diy
synced 2025-06-26 18:26:38 +00:00
Merge b3628b551c
into d0d9818964
This commit is contained in:
commit
af2c8a7f4b
@ -27,6 +27,7 @@ import { logStore } from '~/lib/stores/logs';
|
|||||||
import { streamingState } from '~/lib/stores/streaming';
|
import { streamingState } from '~/lib/stores/streaming';
|
||||||
import { filesToArtifacts } from '~/utils/fileUtils';
|
import { filesToArtifacts } from '~/utils/fileUtils';
|
||||||
import { supabaseConnection } from '~/lib/stores/supabase';
|
import { supabaseConnection } from '~/lib/stores/supabase';
|
||||||
|
import type { DataStreamError } from '~/types/context';
|
||||||
import { defaultDesignScheme, type DesignScheme } from '~/types/design-scheme';
|
import { defaultDesignScheme, type DesignScheme } from '~/types/design-scheme';
|
||||||
import type { ElementInfo } from '~/components/workbench/Inspector';
|
import type { ElementInfo } from '~/components/workbench/Inspector';
|
||||||
|
|
||||||
@ -146,8 +147,13 @@ export const ChatImpl = memo(
|
|||||||
const { showChat } = useStore(chatStore);
|
const { showChat } = useStore(chatStore);
|
||||||
const [animationScope, animate] = useAnimate();
|
const [animationScope, animate] = useAnimate();
|
||||||
const [apiKeys, setApiKeys] = useState<Record<string, string>>({});
|
const [apiKeys, setApiKeys] = useState<Record<string, string>>({});
|
||||||
|
|
||||||
|
// Keep track of the errors we alerted on. useChat gets the same data twice even if they're removed with setData
|
||||||
|
const alertedErrorIds = useRef(new Set());
|
||||||
|
|
||||||
const [chatMode, setChatMode] = useState<'discuss' | 'build'>('build');
|
const [chatMode, setChatMode] = useState<'discuss' | 'build'>('build');
|
||||||
const [selectedElement, setSelectedElement] = useState<ElementInfo | null>(null);
|
const [selectedElement, setSelectedElement] = useState<ElementInfo | null>(null);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
messages,
|
messages,
|
||||||
isLoading,
|
isLoading,
|
||||||
@ -193,7 +199,10 @@ export const ChatImpl = memo(
|
|||||||
},
|
},
|
||||||
onFinish: (message, response) => {
|
onFinish: (message, response) => {
|
||||||
const usage = response.usage;
|
const usage = response.usage;
|
||||||
setData(undefined);
|
setData(() => {
|
||||||
|
alertedErrorIds.current.clear();
|
||||||
|
return undefined;
|
||||||
|
});
|
||||||
|
|
||||||
if (usage) {
|
if (usage) {
|
||||||
console.log('Token usage:', usage);
|
console.log('Token usage:', usage);
|
||||||
@ -232,6 +241,21 @@ export const ChatImpl = memo(
|
|||||||
}
|
}
|
||||||
}, [model, provider, searchParams]);
|
}, [model, provider, searchParams]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (chatData) {
|
||||||
|
for (const data of chatData) {
|
||||||
|
if (data && typeof data === 'object' && 'type' in data && data.type === 'error') {
|
||||||
|
const error = data as DataStreamError;
|
||||||
|
|
||||||
|
if (!alertedErrorIds.current.has(error.id)) {
|
||||||
|
toast.error('There was an error processing your request: ' + error.message);
|
||||||
|
alertedErrorIds.current.add(error.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [chatData]);
|
||||||
|
|
||||||
const { enhancingPrompt, promptEnhanced, enhancePrompt, resetEnhancer } = usePromptEnhancer();
|
const { enhancingPrompt, promptEnhanced, enhancePrompt, resetEnhancer } = usePromptEnhancer();
|
||||||
const { parsedMessages, parseMessages } = useMessageParser();
|
const { parsedMessages, parseMessages } = useMessageParser();
|
||||||
|
|
||||||
|
@ -100,6 +100,8 @@ const ProgressItem = ({ progress }: { progress: ProgressAnnotation }) => {
|
|||||||
<div className="i-svg-spinners:90-ring-with-bg"></div>
|
<div className="i-svg-spinners:90-ring-with-bg"></div>
|
||||||
) : progress.status === 'complete' ? (
|
) : progress.status === 'complete' ? (
|
||||||
<div className="i-ph:check"></div>
|
<div className="i-ph:check"></div>
|
||||||
|
) : progress.status === 'error' ? (
|
||||||
|
<div className="i-ph:warning"></div>
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
{/* {x.label} */}
|
{/* {x.label} */}
|
||||||
|
@ -3,11 +3,10 @@ import { createDataStream, generateId } from 'ai';
|
|||||||
import { MAX_RESPONSE_SEGMENTS, MAX_TOKENS, type FileMap } from '~/lib/.server/llm/constants';
|
import { MAX_RESPONSE_SEGMENTS, MAX_TOKENS, type FileMap } from '~/lib/.server/llm/constants';
|
||||||
import { CONTINUE_PROMPT } from '~/lib/common/prompts/prompts';
|
import { CONTINUE_PROMPT } from '~/lib/common/prompts/prompts';
|
||||||
import { streamText, type Messages, type StreamingOptions } from '~/lib/.server/llm/stream-text';
|
import { streamText, type Messages, type StreamingOptions } from '~/lib/.server/llm/stream-text';
|
||||||
import SwitchableStream from '~/lib/.server/llm/switchable-stream';
|
|
||||||
import type { IProviderSetting } from '~/types/model';
|
import type { IProviderSetting } from '~/types/model';
|
||||||
import { createScopedLogger } from '~/utils/logger';
|
import { createScopedLogger } from '~/utils/logger';
|
||||||
import { getFilePaths, selectContext } from '~/lib/.server/llm/select-context';
|
import { getFilePaths, selectContext } from '~/lib/.server/llm/select-context';
|
||||||
import type { ContextAnnotation, ProgressAnnotation } from '~/types/context';
|
import type { ContextAnnotation, DataStreamError, ProgressAnnotation } from '~/types/context';
|
||||||
import { WORK_DIR } from '~/utils/constants';
|
import { WORK_DIR } from '~/utils/constants';
|
||||||
import { createSummary } from '~/lib/.server/llm/create-summary';
|
import { createSummary } from '~/lib/.server/llm/create-summary';
|
||||||
import { extractPropertiesFromMessage } from '~/lib/.server/llm/utils';
|
import { extractPropertiesFromMessage } from '~/lib/.server/llm/utils';
|
||||||
@ -61,7 +60,7 @@ async function chatAction({ context, request }: ActionFunctionArgs) {
|
|||||||
parseCookies(cookieHeader || '').providers || '{}',
|
parseCookies(cookieHeader || '').providers || '{}',
|
||||||
);
|
);
|
||||||
|
|
||||||
const stream = new SwitchableStream();
|
let responseSegments = 0;
|
||||||
|
|
||||||
const cumulativeUsage = {
|
const cumulativeUsage = {
|
||||||
completionTokens: 0,
|
completionTokens: 0,
|
||||||
@ -220,15 +219,30 @@ async function chatAction({ context, request }: ActionFunctionArgs) {
|
|||||||
} satisfies ProgressAnnotation);
|
} satisfies ProgressAnnotation);
|
||||||
await new Promise((resolve) => setTimeout(resolve, 0));
|
await new Promise((resolve) => setTimeout(resolve, 0));
|
||||||
|
|
||||||
// stream.close();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stream.switches >= MAX_RESPONSE_SEGMENTS) {
|
responseSegments++;
|
||||||
throw Error('Cannot continue message: Maximum segments reached');
|
|
||||||
|
if (responseSegments >= MAX_RESPONSE_SEGMENTS) {
|
||||||
|
dataStream.writeData({
|
||||||
|
type: 'error',
|
||||||
|
id: generateId(),
|
||||||
|
message: 'Cannot continue message: Maximum segments reached.',
|
||||||
|
} satisfies DataStreamError);
|
||||||
|
dataStream.writeData({
|
||||||
|
type: 'progress',
|
||||||
|
label: 'summary',
|
||||||
|
status: 'error',
|
||||||
|
order: progressCounter++,
|
||||||
|
message: 'Error: maximum segments reached.',
|
||||||
|
} satisfies ProgressAnnotation);
|
||||||
|
await new Promise((resolve) => setTimeout(resolve, 0));
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const switchesLeft = MAX_RESPONSE_SEGMENTS - stream.switches;
|
const switchesLeft = MAX_RESPONSE_SEGMENTS - responseSegments;
|
||||||
|
|
||||||
logger.info(`Reached max token limit (${MAX_TOKENS}): Continuing message (${switchesLeft} switches left)`);
|
logger.info(`Reached max token limit (${MAX_TOKENS}): Continuing message (${switchesLeft} switches left)`);
|
||||||
|
|
||||||
|
@ -12,7 +12,13 @@ export type ContextAnnotation =
|
|||||||
export type ProgressAnnotation = {
|
export type ProgressAnnotation = {
|
||||||
type: 'progress';
|
type: 'progress';
|
||||||
label: string;
|
label: string;
|
||||||
status: 'in-progress' | 'complete';
|
status: 'in-progress' | 'complete' | 'error';
|
||||||
order: number;
|
order: number;
|
||||||
message: string;
|
message: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type DataStreamError = {
|
||||||
|
type: 'error';
|
||||||
|
id: string;
|
||||||
|
message: string;
|
||||||
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user