mirror of
https://github.com/browseros-ai/BrowserOS.git
synced 2026-05-18 11:06:19 +00:00
Merge branch 'main' of https://github.com/browseros-ai/BrowserOS-agent
This commit is contained in:
@@ -30,7 +30,41 @@ export function generateSystemPrompt(): string {
|
||||
- Always refer to the content within <browser-state> tags when answering questions about the page
|
||||
- This browser state is automatically updated when tabs change
|
||||
|
||||
## Instructions
|
||||
## CRITICAL: Chat Mode Limitations
|
||||
You are currently in **Chat Mode**, which is READ-ONLY and designed for Q&A only.
|
||||
|
||||
### Action Detection Rules
|
||||
If the user's request involves ANY of these action types, you MUST respond with the Agent Mode guidance template:
|
||||
|
||||
**Direct Actions:**
|
||||
- Clicking, tapping, or selecting elements
|
||||
- Typing, filling forms, entering text
|
||||
- Navigating, opening URLs, going to pages
|
||||
- Submitting forms, pressing buttons
|
||||
- Uploading or downloading files
|
||||
- Making purchases, adding to cart, checkout
|
||||
- Signing in, logging in, registering
|
||||
- Playing, pausing, controlling media
|
||||
- Creating, sending, or posting content
|
||||
- Booking, applying, subscribing to services
|
||||
- Installing, deleting, or managing content
|
||||
|
||||
**Intent Indicators:**
|
||||
- Commands starting with action verbs: "click the button", "open this link"
|
||||
- Polite requests: "can you please click", "could you help me navigate"
|
||||
- Task requests: "help me fill out this form", "assist me in buying this"
|
||||
- Page interaction: "click on this page", "navigate to the next section"
|
||||
|
||||
### Required Response Template
|
||||
When you detect ANY action request, respond EXACTLY with this template:
|
||||
|
||||
You’re in Chat Mode right now, which is great for asking questions or understanding page content.
|
||||
To actually execute actions, please switch to Agent Mode.
|
||||
|
||||
I can still help you understand what's on the page or answer questions about the content though!
|
||||
|
||||
## Q&A Instructions
|
||||
For legitimate questions (not action requests):
|
||||
1. Be concise and direct in your responses
|
||||
2. Answer based on the page content within <browser-state> tags
|
||||
3. Use tools only when necessary for answering the question
|
||||
|
||||
@@ -25,63 +25,16 @@ interface MessageListProps {
|
||||
containerRef?: React.RefObject<HTMLDivElement>
|
||||
}
|
||||
|
||||
// Example prompts grouped by category
|
||||
const ALL_EXAMPLES = [
|
||||
// Tab Management
|
||||
"Group my tabs by app or purpose",
|
||||
"Find tabs related to machine learning",
|
||||
// "Close tabs I haven't touched in 7 days",
|
||||
"Highlight the tab where I was last shopping",
|
||||
"Save all Facebook tabs to a reading list",
|
||||
// "Pin tabs I use daily",
|
||||
// "Archive tabs from last week's research",
|
||||
// "Reopen the tab I accidentally closed",
|
||||
// "Mute all tabs except the one playing music",
|
||||
|
||||
// Page Analysis
|
||||
"Summarize this article for me",
|
||||
"What are the key points on this page?",
|
||||
// "Check if this article is AI-generated",
|
||||
"Extract all links and sources from this page",
|
||||
"Extract all news headlines from this page",
|
||||
// "List all images and their alt text",
|
||||
// "Detect the reading level of this article",
|
||||
// "Highlight quotes or cited studies",
|
||||
// "Compare this page to another tab I'm viewing",
|
||||
|
||||
// Search & Discovery
|
||||
"Find top-rated headphones under $100",
|
||||
// "Find the cheapest flight to San Francisco",
|
||||
"Search YouTube for videos explaining BrowserOS",
|
||||
// "Look up reviews for this product",
|
||||
"Search Reddit for discussions about this topic",
|
||||
// "Find recipes using the ingredients in my tabs",
|
||||
// "Show me recent news about this company",
|
||||
// "Search for open-source alternatives to this tool",
|
||||
|
||||
// Actions & Automation
|
||||
// Example prompts - showcasing BrowserOS capabilities
|
||||
const EXAMPLES = [
|
||||
"Open amazon.com and order Sensodyne toothpaste",
|
||||
"Write a tweet saying Hello World",
|
||||
// "Add this page to my bookmarks",
|
||||
// "Download the PDF linked on this page",
|
||||
// "Translate this page to Spanish",
|
||||
// "Email this article to myself",
|
||||
// "Create a calendar event based on this page",
|
||||
// "Copy all code snippets from this tab",
|
||||
|
||||
// AI & Content Tools
|
||||
// "Rewrite this paragraph to be more concise",
|
||||
"Generate a summary tweet for this article",
|
||||
// "Explain this code like I'm five",
|
||||
// "Draft a reply to this comment",
|
||||
"Rate the tone of this blog post",
|
||||
// "Suggest improvements to this documentation",
|
||||
"Find top-rated headphones under $200",
|
||||
"Go to GitHub and Star BrowserOS",
|
||||
"Turn this article into a LinkedIn post",
|
||||
// "Detect bias or opinionated language in this page",
|
||||
]
|
||||
|
||||
// Animation constants
|
||||
const DEFAULT_DISPLAY_COUNT = 5 // Default number of examples to show
|
||||
const DEFAULT_DISPLAY_COUNT = 4 // Fixed number of examples to show
|
||||
|
||||
/**
|
||||
* MessageList component
|
||||
@@ -91,10 +44,9 @@ export function MessageList({ messages, isProcessing = false, onScrollStateChang
|
||||
const { containerRef: internalContainerRef, isUserScrolling, scrollToBottom } = useAutoScroll<HTMLDivElement>([messages], externalContainerRef)
|
||||
const { trackFeature } = useAnalytics()
|
||||
const [, setIsAtBottom] = useState(true)
|
||||
const [currentExamples, setCurrentExamples] = useState<string[]>([])
|
||||
const [shuffledPool, setShuffledPool] = useState<string[]>([])
|
||||
const [currentExamples] = useState<string[]>(EXAMPLES)
|
||||
const [isAnimating] = useState(false)
|
||||
const [displayCount, setDisplayCount] = useState(DEFAULT_DISPLAY_COUNT)
|
||||
const [displayCount] = useState(DEFAULT_DISPLAY_COUNT)
|
||||
|
||||
// Track previously seen message IDs to determine which are new
|
||||
const previousMessageIdsRef = useRef<Set<string>>(new Set())
|
||||
@@ -103,19 +55,8 @@ export function MessageList({ messages, isProcessing = false, onScrollStateChang
|
||||
// Use external container ref if provided, otherwise use internal one
|
||||
const containerRef = externalContainerRef || internalContainerRef
|
||||
|
||||
// Adjust display count based on viewport height
|
||||
useEffect(() => {
|
||||
const updateDisplayCount = () => {
|
||||
const height = window.innerHeight
|
||||
setDisplayCount(height < 700 ? 3 : DEFAULT_DISPLAY_COUNT)
|
||||
}
|
||||
|
||||
updateDisplayCount()
|
||||
window.addEventListener('resize', updateDisplayCount)
|
||||
return () => window.removeEventListener('resize', updateDisplayCount)
|
||||
}, [])
|
||||
|
||||
// Track new messages for animation
|
||||
// Track new messages for animation
|
||||
useEffect(() => {
|
||||
const currentMessageIds = new Set(messages.map(msg => msg.msgId))
|
||||
const previousIds = previousMessageIdsRef.current
|
||||
@@ -208,55 +149,6 @@ export function MessageList({ messages, isProcessing = false, onScrollStateChang
|
||||
return blocks
|
||||
}, [messages])
|
||||
|
||||
// Initialize shuffled pool and current examples
|
||||
useEffect(() => {
|
||||
const shuffled = [...ALL_EXAMPLES].sort(() => 0.5 - Math.random())
|
||||
setShuffledPool(shuffled)
|
||||
|
||||
// Get initial examples based on display count
|
||||
const initialExamples: string[] = []
|
||||
for (let i = 0; i < displayCount; i++) {
|
||||
if (shuffled.length > 0) {
|
||||
initialExamples.push(shuffled.pop()!)
|
||||
}
|
||||
}
|
||||
setCurrentExamples(initialExamples)
|
||||
}, [displayCount])
|
||||
|
||||
// Function to get random examples from pool
|
||||
const _getRandomExample = useCallback((count: number = 1): string[] => {
|
||||
const result: string[] = []
|
||||
let pool = [...shuffledPool]
|
||||
|
||||
while (result.length < count) {
|
||||
// If exhausted, reshuffle
|
||||
if (pool.length === 0) {
|
||||
pool = [...ALL_EXAMPLES].sort(() => 0.5 - Math.random())
|
||||
}
|
||||
result.push(pool.pop()!)
|
||||
}
|
||||
|
||||
// Update the pool
|
||||
setShuffledPool(pool)
|
||||
return result
|
||||
}, [shuffledPool])
|
||||
|
||||
// Refresh examples only when the welcome view is shown (on mount or when messages become empty)
|
||||
const wasEmptyRef = useRef<boolean>(messages.length === 0)
|
||||
useEffect(() => {
|
||||
const isEmpty = messages.length === 0
|
||||
if (isEmpty && !wasEmptyRef.current) {
|
||||
// Reinitialize examples when transitioning back to empty state
|
||||
const shuffled = [...ALL_EXAMPLES].sort(() => 0.5 - Math.random())
|
||||
setShuffledPool(shuffled)
|
||||
const initialExamples: string[] = []
|
||||
for (let i = 0; i < displayCount; i++) {
|
||||
if (shuffled.length > 0) initialExamples.push(shuffled.pop()!)
|
||||
}
|
||||
setCurrentExamples(initialExamples)
|
||||
}
|
||||
wasEmptyRef.current = isEmpty
|
||||
}, [messages.length, displayCount])
|
||||
|
||||
// Check if we're at the bottom of the scroll container
|
||||
useEffect(() => {
|
||||
|
||||
Reference in New Issue
Block a user