mirror of
https://github.com/stackblitz-labs/bolt.diy
synced 2025-06-25 17:56:12 +00:00
fix: fix prompt continuation
This commit is contained in:
parent
f0aa58c922
commit
3e1bcb9849
@ -531,16 +531,18 @@ export const ChatImpl = memo(
|
||||
description={description}
|
||||
importChat={importChat}
|
||||
exportChat={exportChat}
|
||||
messages={messages.map((message, i) => {
|
||||
if (message.role === 'user') {
|
||||
return message;
|
||||
}
|
||||
messages={messages
|
||||
.filter((message, i) => (message.role === 'assistant' ? parsedMessages[i] : true))
|
||||
.map((message, i) => {
|
||||
if (message.role === 'user') {
|
||||
return message;
|
||||
}
|
||||
|
||||
return {
|
||||
...message,
|
||||
content: parsedMessages[i] || '',
|
||||
};
|
||||
})}
|
||||
return {
|
||||
...message,
|
||||
content: parsedMessages[i] || '',
|
||||
};
|
||||
})}
|
||||
enhancePrompt={() => {
|
||||
enhancePrompt(
|
||||
input,
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { WORK_DIR } from '~/utils/constants';
|
||||
import { allowedHTMLElements } from '~/utils/markdown';
|
||||
import { stripIndents } from '~/utils/stripIndent';
|
||||
|
||||
export const getFineTunedPrompt = (
|
||||
cwd: string = WORK_DIR,
|
||||
@ -695,7 +694,12 @@ npm run dev
|
||||
</example>
|
||||
</examples>`;
|
||||
|
||||
export const CONTINUE_PROMPT = stripIndents`
|
||||
Continue your prior response. IMPORTANT: Immediately begin from where you left off without any interruptions.
|
||||
Do not repeat any content, including artifact and action tags.
|
||||
`;
|
||||
export const CONTINUE_PROMPT = `Continue your prior response.
|
||||
Important: continue your last message without any interruptions, even if you're in the middle of a thought. You are continuing a document that will be re-assembled later. Never repeat any text that has already been sent.
|
||||
Example:
|
||||
Previous message:
|
||||
<boltAction filePath="index.html"><!DOCTYPE html><html lang
|
||||
Bad: Repeats the previous message. This creates an unreadable document.
|
||||
<boltAction filePath="index.html"><!DOCTYPE html><html lang="en"><body>
|
||||
Good: Continues from where the previous message left off:
|
||||
="en"><body>`;
|
||||
|
@ -698,7 +698,12 @@ Here are some examples of correct usage of artifacts:
|
||||
</examples>
|
||||
`;
|
||||
|
||||
export const CONTINUE_PROMPT = stripIndents`
|
||||
Continue your prior response. IMPORTANT: Immediately begin from where you left off without any interruptions.
|
||||
Do not repeat any content, including artifact and action tags.
|
||||
`;
|
||||
export const CONTINUE_PROMPT = `Continue your prior response.
|
||||
Important: continue your last message without any interruptions, even if you're in the middle of a thought. You are continuing a document that will be re-assembled later. Never repeat any text that has already been sent.
|
||||
Example:
|
||||
Previous message:
|
||||
<boltAction filePath="index.html"><!DOCTYPE html><html lang
|
||||
Bad: Repeats the previous message. This creates an unreadable document.
|
||||
<boltAction filePath="index.html"><!DOCTYPE html><html lang="en"><body>
|
||||
Good: Continues from where the previous message left off:
|
||||
="en"><body>`;
|
||||
|
@ -1,7 +1,8 @@
|
||||
import type { Message } from 'ai';
|
||||
import type { JSONValue, Message } from 'ai';
|
||||
import { useCallback, useState } from 'react';
|
||||
import { StreamingMessageParser } from '~/lib/runtime/message-parser';
|
||||
import { workbenchStore } from '~/lib/stores/workbench';
|
||||
import type { SegmentsGroupAnnotation } from '~/types/context';
|
||||
import { createScopedLogger } from '~/utils/logger';
|
||||
|
||||
const logger = createScopedLogger('useMessageParser');
|
||||
@ -47,6 +48,14 @@ const extractTextContent = (message: Message) =>
|
||||
? (message.content.find((item) => item.type === 'text')?.text as string) || ''
|
||||
: message.content;
|
||||
|
||||
const segmentsGroupIdFromAnnotation = (annotation: JSONValue): string | null => {
|
||||
if (annotation && typeof annotation === 'object' && 'type' in annotation && annotation.type === 'segmentsGroup') {
|
||||
return (annotation as SegmentsGroupAnnotation).segmentsGroupId;
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
export function useMessageParser() {
|
||||
const [parsedMessages, setParsedMessages] = useState<{ [key: number]: string }>({});
|
||||
|
||||
@ -58,13 +67,44 @@ export function useMessageParser() {
|
||||
messageParser.reset();
|
||||
}
|
||||
|
||||
const messageContents: Record<number, string> = {};
|
||||
const segmentGroups: Record<string, { firstGroupIndex: number }> = {};
|
||||
|
||||
for (const [index, message] of messages.entries()) {
|
||||
if (message.role === 'user') {
|
||||
messageContents[index] = extractTextContent(message);
|
||||
} else if (message.role === 'assistant') {
|
||||
const segmentsGroupId = message.annotations?.reduce(
|
||||
(groupId: string | null, a) => groupId ?? segmentsGroupIdFromAnnotation(a),
|
||||
null,
|
||||
);
|
||||
|
||||
if (!segmentsGroupId) {
|
||||
messageContents[index] = extractTextContent(message);
|
||||
} else {
|
||||
const firstIndex = segmentGroups[segmentsGroupId]?.firstGroupIndex;
|
||||
|
||||
if (firstIndex === undefined) {
|
||||
segmentGroups[segmentsGroupId] = { firstGroupIndex: index };
|
||||
messageContents[index] = extractTextContent(message);
|
||||
} else {
|
||||
messageContents[firstIndex] += extractTextContent(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const [index, message] of messages.entries()) {
|
||||
if (message.role === 'assistant' || message.role === 'user') {
|
||||
const newParsedContent = messageParser.parse(message.id, extractTextContent(message));
|
||||
setParsedMessages((prevParsed) => ({
|
||||
...prevParsed,
|
||||
[index]: !reset ? (prevParsed[index] || '') + newParsedContent : newParsedContent,
|
||||
}));
|
||||
const content = messageContents[index];
|
||||
|
||||
if (content !== undefined) {
|
||||
const newParsedContent = messageParser.parse(message.id, content);
|
||||
setParsedMessages((prevParsed) => ({
|
||||
...prevParsed,
|
||||
[index]: !reset ? (prevParsed[index] || '') + newParsedContent : newParsedContent,
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
}, []);
|
||||
|
@ -7,7 +7,7 @@ import SwitchableStream from '~/lib/.server/llm/switchable-stream';
|
||||
import type { IProviderSetting } from '~/types/model';
|
||||
import { createScopedLogger } from '~/utils/logger';
|
||||
import { getFilePaths, selectContext } from '~/lib/.server/llm/select-context';
|
||||
import type { ContextAnnotation, ProgressAnnotation } from '~/types/context';
|
||||
import type { ContextAnnotation, ProgressAnnotation, SegmentsGroupAnnotation } from '~/types/context';
|
||||
import { WORK_DIR } from '~/utils/constants';
|
||||
import { createSummary } from '~/lib/.server/llm/create-summary';
|
||||
import { extractPropertiesFromMessage } from '~/lib/.server/llm/utils';
|
||||
@ -59,6 +59,7 @@ async function chatAction({ context, request }: ActionFunctionArgs) {
|
||||
);
|
||||
|
||||
const stream = new SwitchableStream();
|
||||
const segmentsGroupId = generateId();
|
||||
|
||||
const cumulativeUsage = {
|
||||
completionTokens: 0,
|
||||
@ -238,6 +239,11 @@ async function chatAction({ context, request }: ActionFunctionArgs) {
|
||||
content: `[Model: ${model}]\n\n[Provider: ${provider}]\n\n${CONTINUE_PROMPT}`,
|
||||
});
|
||||
|
||||
dataStream.writeMessageAnnotation({
|
||||
type: 'segmentsGroup',
|
||||
segmentsGroupId,
|
||||
} satisfies SegmentsGroupAnnotation);
|
||||
|
||||
const result = await streamText({
|
||||
messages,
|
||||
env: context.cloudflare?.env,
|
||||
|
@ -16,3 +16,8 @@ export type ProgressAnnotation = {
|
||||
order: number;
|
||||
message: string;
|
||||
};
|
||||
|
||||
export type SegmentsGroupAnnotation = {
|
||||
type: 'segmentsGroup';
|
||||
segmentsGroupId: string;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user