diff --git a/ui/desktop/src/ChatWindow.tsx b/ui/desktop/src/ChatWindow.tsx
index e027c1c470..bc7eed288c 100644
--- a/ui/desktop/src/ChatWindow.tsx
+++ b/ui/desktop/src/ChatWindow.tsx
@@ -97,9 +97,6 @@ function ChatContent({
onFinish: async (message, options) => {
setStatus('Goose is ready');
-
-
-
const promptTemplates = [
"Take a look at this content, if this looks like it could be asking for a confirmation, return QUESTION. If it looks like it is a list of options or plans to choose from, return OPTIONS, otherwise return READY. \n ### Message Content:\n" + message.content,
"If the content is clearly a list of distinct options or plans of action to choose from, and not just a list of things, but clearly a list of things to choose one from from, take into account the Message Content alone, try to format it in a json array, like this JSON array of objects of the form optionTitle:string, optionDescription:string (markdown).\n If is not a list of options or plans to choose from, then return empty list.\n ### Message Content:\n" + message.content,
@@ -178,7 +175,12 @@ function ChatContent({
{message.role === 'user' ? (
) : (
-
+
)}
))}
@@ -247,8 +249,6 @@ export default function ChatWindow() {
return (
-
-
{/* Always render ChatContent but control its visibility */}
@@ -276,9 +276,6 @@ export default function ChatWindow() {
);
-
-
-
}
/**
@@ -307,4 +304,3 @@ async function askAi(promptTemplates: string[]) {
return responses;
}
-
diff --git a/ui/desktop/src/components/GooseMessage.tsx b/ui/desktop/src/components/GooseMessage.tsx
index a196fddaa3..0c0255292c 100644
--- a/ui/desktop/src/components/GooseMessage.tsx
+++ b/ui/desktop/src/components/GooseMessage.tsx
@@ -1,148 +1,62 @@
-import React, { useState } from 'react';
+import React from 'react';
import ToolInvocation from './ToolInvocation';
import ReactMarkdown from 'react-markdown';
-import { GPSIcon } from './ui/icons';
+import LinkPreview from './LinkPreview';
+import GooseResponseForm from './GooseResponseForm';
+import { extractUrls } from '../utils/urlUtils';
interface GooseMessageProps {
message: any;
- metadata: any;
- onInputChange?: (value: string) => void;
+ messages: any[];
+ metadata?: any;
+ append: (value: any) => void;
}
-export default function GooseMessage({ message, metadata, onInputChange }: GooseMessageProps) {
- console.log("GooseMessage", metadata);
+export default function GooseMessage({ message, metadata, messages, append }: GooseMessageProps) {
+ // Find the preceding user message
+ const messageIndex = messages?.findIndex(msg => msg.id === message.id);
+ const previousMessage = messageIndex > 0 ? messages[messageIndex - 1] : null;
- let isReady = false;
- let isQuestion = false;
- let isOptions = false;
- let options = [];
+ // Get URLs from previous user message (if it exists)
+ const previousUrls = previousMessage
+ ? extractUrls(previousMessage.content)
+ : [];
- if (metadata) {
- isReady = metadata[0] === "READY";
- isQuestion = metadata[0] === "QUESTION";
- isOptions = metadata[0] === "OPTIONS";
-
- if (isOptions && metadata[1]) {
- try {
- let optionsData = metadata[1];
-
- // Remove ```json block if present
- if (optionsData.startsWith('```json')) {
- optionsData = optionsData.replace(/```json/g, '').replace(/```/g, '');
- }
-
- // Parse the options JSON
- options = JSON.parse(optionsData);
-
- // Validate the structure of each option
- options = options.filter(
- (opt) =>
- typeof opt.optionTitle === 'string' &&
- typeof opt.optionDescription === 'string'
- );
- } catch (err) {
- console.error("Failed to parse options data:", err);
- options = [];
- }
- }
- }
-
- const [selectedOption, setSelectedOption] = useState(null);
-
- const handleOptionClick = (index) => {
- setSelectedOption(index);
- };
-
- const handleAccept = () => {
- if (onInputChange) {
- onInputChange({ target: { value: "accept" } } as React.ChangeEvent);
- }
- };
-
- const handleCancel = () => {
- if (onInputChange) {
- onInputChange({ target: { value: "No thanks" } } as React.ChangeEvent);
- }
- };
-
- const handleSubmit = () => {
- if (selectedOption !== null && onInputChange) {
- onInputChange({ target: { value: options[selectedOption].optionTitle } } as React.ChangeEvent);
- }
- };
-
- if (isQuestion || isOptions) {
- window.electron.showNotification({
- title: 'Goose has a question for you',
- body: `please check with goose to approve the plan of action`,
- });
- }
+ // Extract URLs from current message, excluding those from the previous user message
+ const urls = extractUrls(message.content, previousUrls);
return (
-