diff --git a/core/framework/agents/hive_coder/nodes/__init__.py b/core/framework/agents/hive_coder/nodes/__init__.py index 448e3a90..cdcaa695 100644 --- a/core/framework/agents/hive_coder/nodes/__init__.py +++ b/core/framework/agents/hive_coder/nodes/__init__.py @@ -609,10 +609,17 @@ Examples: When the user greets you, respond concisely (under 10 lines) with worker \ status only: -1. State whether a worker[worker name] is loaded and whether it is running, staging, or not loaded. -2. If loaded, include one sentence on what the worker does (from Worker Profile). +1. Use plain, user-facing wording about load/run state; avoid internal phase \ +labels ("staging phase", "building phase", "running phase") unless the user \ +explicitly asks for phase details. +2. If loaded, prefer this format: " has been loaded. ." 3. Do NOT include identity details unless the user explicitly asks about identity. 4. THEN call ask_user to prompt them — do NOT just write text. +5. Preferred loaded example: + local_business_extractor/*agent name*/ has been loaded. It finds local businesses on \ +Google Maps, extracts contact details, and syncs them to Google Sheets. + ask_user("Do you want to run it?", ["Yes, run it", "Check credentials first", "Modify the worker"]) ## When user ask identity and responsibility @@ -670,7 +677,9 @@ NEVER call run_agent_with_input until the user has provided their input. If NO worker is loaded, say so and offer to build one. ## When in staging phase (agent loaded, not running): -- Tell the user the agent is loaded and ready. +- Tell the user the agent is loaded and ready in plain language (for example, \ +" has been loaded."). +- Avoid lead-ins like "A worker is loaded and ready in staging phase: ...". - For tasks matching the worker's goal: ALWAYS ask the user for their \ specific input BEFORE calling run_agent_with_input(task). NEVER make up \ or assume what the user wants. Use ask_user to collect the task details \ diff --git a/core/frontend/src/components/ChatPanel.tsx b/core/frontend/src/components/ChatPanel.tsx index 260d1d4d..1c87767c 100644 --- a/core/frontend/src/components/ChatPanel.tsx +++ b/core/frontend/src/components/ChatPanel.tsx @@ -284,7 +284,8 @@ export default function ChatPanel({ messages, onSend, isWaiting, isWorkerWaiting ))} - {isWaiting && ( + {/* Show typing indicator while waiting for first queen response (disabled + empty chat) */} + {(isWaiting || (disabled && threadMessages.length === 0)) && (
0 || !!coldRestoreId; updateAgentState(agentType, { sessionId: session.session_id, displayName, ready: true, loading: false, - queenReady: true, + queenReady: !!(isResumedSession || hasRestoredContent), ...(isWorkerRunning ? { workerRunState: "running" } : {}), }); } catch (err: unknown) { @@ -1272,16 +1279,17 @@ export default function Workspace() { // Backend event timestamp for correct queen/worker message ordering const eventCreatedAt = event.timestamp ? new Date(event.timestamp).getTime() : Date.now(); - // Mark queen as ready on the first queen SSE event - if (isQueen && !agentStates[agentType]?.queenReady) { - updateAgentState(agentType, { queenReady: true }); - } + // Mark queen as ready on the first queen SSE event. + // Deferred to individual event handlers below so we can batch it with + // other state updates (e.g. queenIsTyping) and avoid a flash frame + // where queenReady=true but queenIsTyping=false. + const shouldMarkQueenReady = isQueen && !agentStates[agentType]?.queenReady; switch (event.type) { case "execution_started": if (isQueen) { turnCounterRef.current[turnKey] = currentTurn + 1; - updateAgentState(agentType, { isTyping: true, queenIsTyping: true }); + updateAgentState(agentType, { isTyping: true, queenIsTyping: true, ...(shouldMarkQueenReady && { queenReady: true }) }); } else { // Warn if prior LLM snapshots are being dropped (edge case: execution_completed never arrived) const priorSnapshots = agentStates[agentType]?.llmSnapshots || {}; @@ -1835,6 +1843,8 @@ export default function Workspace() { } default: + // Fallback: ensure queenReady is set even for unexpected first events + if (shouldMarkQueenReady) updateAgentState(agentType, { queenReady: true }); break; } }, diff --git a/examples/templates/local_business_extractor/nodes/__init__.py b/examples/templates/local_business_extractor/nodes/__init__.py index 65a86d18..26c4e16c 100644 --- a/examples/templates/local_business_extractor/nodes/__init__.py +++ b/examples/templates/local_business_extractor/nodes/__init__.py @@ -19,7 +19,8 @@ You are a browser agent. Your job: Search Google Maps for the provided query and ## Workflow 1. browser_start 2. browser_open(url="https://www.google.com/maps") -3. Use browser_type or browser_click to search for the "query" in memory. +3. use the url query to search for the keyword +3.1 alternatively, use browser_type or browser_click to search for the "query" in memory.' 4. browser_wait(seconds=3) 5. browser_snapshot to find the list of results. 6. For each relevant result, extract: