diff --git a/frontend-web/src/pages/IframeChatPage.tsx b/frontend-web/src/pages/IframeChatPage.tsx index 821b0ef5..8623e45b 100644 --- a/frontend-web/src/pages/IframeChatPage.tsx +++ b/frontend-web/src/pages/IframeChatPage.tsx @@ -138,6 +138,7 @@ export default function IframeChatPage() { ( message: PromptInputMessage, externalContext?: Record, + options?: { additionalKwargs?: Record }, ) => { if ( selectedAgentId && @@ -183,6 +184,7 @@ export default function IframeChatPage() { threadId, message, Object.keys(extraContext).length > 0 ? extraContext : undefined, + options, ); }, [ @@ -213,7 +215,7 @@ export default function IframeChatPage() { if (data?.source !== "brainy-extension") return; if (data?.type !== "brainy:chat-submit") return; - const { submitText, files, iframeContext } = + const { submitText, files, iframeContext, additionalKwargs } = parseBrainyChatSubmitMessage(data); console.log("收到插件消息", { @@ -229,7 +231,11 @@ export default function IframeChatPage() { pendingRequestIdRef.current = data.requestId ?? null; - handleSubmit({ text: submitText, files }, iframeContext); + handleSubmit( + { text: submitText, files }, + iframeContext, + additionalKwargs ? { additionalKwargs } : undefined, + ); }; window.addEventListener("message", handleMessage); diff --git a/frontend-web/src/pages/iframe-chat-submit.test.ts b/frontend-web/src/pages/iframe-chat-submit.test.ts index 1b49c128..517eab42 100644 --- a/frontend-web/src/pages/iframe-chat-submit.test.ts +++ b/frontend-web/src/pages/iframe-chat-submit.test.ts @@ -32,11 +32,16 @@ test("parses iframe text, page context, and screenshot into a prompt message", ( assert.equal(result.submitText, [ "提取并翻译", - "\nA screenshot image is attached for this message.\nUse the attached image as the primary source of truth.\nUse page context and text prompt only as supporting context.\nIf the image conflicts with page context or text, trust the image.\n", - "\n提取图片中的文字并翻译成简体中文\n", - "\n\nUN News\n\n\n\nhttps://news.un.org/example\n\n\n\nBanning children from social media is not the answer.\n\n", ].join("\n\n")); assert.deepEqual(result.iframeContext, { brainy_request_id: "iframe-123" }); + assert.equal( + result.additionalKwargs?.prompt_prefix, + [ + "\nA screenshot image is attached for this message.\nUse the attached image as the primary source of truth.\nUse page context and text prompt only as supporting context.\nIf the image conflicts with page context or text, trust the image.\n", + "\n提取图片中的文字并翻译成简体中文\n", + "\n\nUN News\n\n\n\nhttps://news.un.org/example\n\n\n\nBanning children from social media is not the answer.\n\n", + ].join("\n\n"), + ); assert.equal(result.files.length, 1); assert.equal(result.files[0]?.type, "file"); assert.equal(result.files[0]?.filename, "capture.png"); @@ -65,8 +70,9 @@ test("keeps screenshot-only iframe submissions in the conversation flow", () => }, }); + assert.equal(result.submitText, ""); assert.equal( - result.submitText, + result.additionalKwargs?.prompt_prefix, "\nA screenshot image is attached for this message.\nUse the attached image as the primary source of truth.\nUse page context and text prompt only as supporting context.\nIf the image conflicts with page context or text, trust the image.\n", ); assert.equal(result.files.length, 1); diff --git a/frontend-web/src/pages/iframe-chat-submit.ts b/frontend-web/src/pages/iframe-chat-submit.ts index 981f0634..2396a046 100644 --- a/frontend-web/src/pages/iframe-chat-submit.ts +++ b/frontend-web/src/pages/iframe-chat-submit.ts @@ -45,6 +45,7 @@ export type ParsedBrainyChatSubmitMessage = { submitText: string; files: IframePromptInputFilePart[]; iframeContext?: Record; + additionalKwargs?: Record; }; const IMAGE_PRIORITY_INSTRUCTION = [ @@ -137,30 +138,23 @@ function normalizePageContext( : undefined; } -export function buildIframeMessageText({ - text, +function buildIframePromptPrefix({ prompt, pageContext, hasAttachedImage = false, }: { - text?: string; prompt?: string; pageContext?: BrainyPageContext; hasAttachedImage?: boolean; }) { - const primaryText = trimToUndefined(text) || trimToUndefined(prompt) || ""; const sections: string[] = []; - if (primaryText) { - sections.push(primaryText); - } - if (hasAttachedImage) { sections.push(IMAGE_PRIORITY_INSTRUCTION); } const normalizedPrompt = trimToUndefined(prompt); - if (normalizedPrompt && normalizedPrompt !== primaryText) { + if (normalizedPrompt) { sections.push( `\n${normalizedPrompt}\n`, ); @@ -190,6 +184,17 @@ export function buildIframeMessageText({ return sections.join("\n\n"); } +export function buildIframeMessageText({ + text, + prompt, +}: { + text?: string; + prompt?: string; +}) { + const primaryText = trimToUndefined(text) || trimToUndefined(prompt) || ""; + return primaryText; +} + function buildScreenshotFileParts( screenshot: BrainyScreenshot | undefined, ): IframePromptInputFilePart[] { @@ -249,8 +254,8 @@ export function parseBrainyChatSubmitMessage( const prompt = trimToUndefined(data.payload?.prompt); const pageContext = normalizePageContext(data.payload?.pageContext); const files = buildScreenshotFileParts(data.payload?.screenshot); - const submitText = buildIframeMessageText({ - text, + const submitText = buildIframeMessageText({ text, prompt }); + const promptPrefix = buildIframePromptPrefix({ prompt, pageContext, hasAttachedImage: files.length > 0, @@ -263,5 +268,6 @@ export function parseBrainyChatSubmitMessage( ...(requestId ? { iframeContext: { brainy_request_id: requestId } } : {}), + ...(promptPrefix ? { additionalKwargs: { prompt_prefix: promptPrefix } } : {}), }; }