Skip to content

Commit f2bc7da

Browse files
ngoiyaericManus AI
authored andcommitted
Merge pull request #372 from QueueLab/improve-prompting-efficiency
Feat: Improve prompting for exploration efficiency
2 parents 8718e4c + db1a02b commit f2bc7da

File tree

7 files changed

+10385
-3606
lines changed

7 files changed

+10385
-3606
lines changed

app/actions.tsx

Lines changed: 49 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import type { FeatureCollection } from 'geojson'
1212
import { Spinner } from '@/components/ui/spinner'
1313
import { Section } from '@/components/section'
1414
import { FollowupPanel } from '@/components/followup-panel'
15-
import { inquire, researcher, taskManager, querySuggestor, resolutionSearch } from '@/lib/agents'
15+
import { inquire, researcher, taskManager, querySuggestor, resolutionSearch, toolCoordinator, executeToolPlan, aggregateToolResults } from '@/lib/agents'
1616
// Removed import of useGeospatialToolMcp as it no longer exists and was incorrectly used here.
1717
// The geospatialTool (if used by agents like researcher) now manages its own MCP client.
1818
import { writer } from '@/lib/agents/writer'
@@ -125,6 +125,7 @@ async function submit(formData?: FormData, skip?: boolean) {
125125

126126
const groupeId = nanoid()
127127
const useSpecificAPI = process.env.USE_SPECIFIC_API_FOR_WRITER === 'true'
128+
const useToolCoordinator = process.env.USE_TOOL_COORDINATOR === 'true'
128129
const maxMessages = useSpecificAPI ? 5 : 10
129130
messages.splice(0, Math.max(messages.length - maxMessages, 0))
130131

@@ -319,17 +320,58 @@ async function submit(formData?: FormData, skip?: boolean) {
319320
const streamText = createStreamableValue<string>()
320321
uiStream.update(<Spinner />)
321322

323+
let finalMessages = messages
324+
325+
if (useToolCoordinator) {
326+
uiStream.update(<Spinner text="Planning tool execution..." />)
327+
try {
328+
const plan = await toolCoordinator(messages)
329+
uiStream.update(<Spinner text="Executing tool plan..." />)
330+
const results = await executeToolPlan(plan)
331+
toolOutputs = results
332+
const summary = aggregateToolResults(results, plan)
333+
334+
// Add the summary to the messages for the final synthesis agent
335+
finalMessages = [
336+
...messages,
337+
{
338+
id: nanoid(),
339+
role: 'tool',
340+
content: summary,
341+
type: 'tool_coordinator_summary'
342+
} as any // Cast to any to satisfy CoreMessage type for custom type
343+
]
344+
345+
// Stream a message to the user about the tool execution completion
346+
uiStream.append(
347+
<BotMessage content="Tool execution complete. Synthesizing final answer..." />
348+
)
349+
} catch (e) {
350+
console.error('Tool Coordinator failed:', e)
351+
uiStream.append(
352+
<BotMessage content="Tool Coordinator failed. Falling back to streaming researcher." />
353+
)
354+
// Fallback: continue with the original messages and let the researcher handle it
355+
finalMessages = messages
356+
}
357+
}
358+
322359
while (
323360
useSpecificAPI
324361
? answer.length === 0
325362
: answer.length === 0 && !errorOccurred
326363
) {
327-
const { fullResponse, hasError, toolResponses } = await researcher(
328-
currentSystemPrompt,
329-
uiStream,
330-
streamText,
331-
messages,
332-
useSpecificAPI
364+
// If coordinator was used, pass finalMessages and disable tools for researcher
365+
c const { fullResponse, hasError, toolResponses } = await researcher(
366+
currentSystemPrompt,
367+
uiStream,
368+
streamText,
369+
finalMessages,
370+
useSpecificAPI,
371+
!useToolCoordinator // Pass a flag to disable tools if coordinator was used
372+
)cAPI,
373+
!useToolCoordinator // Pass a flag to disable tools if coordinator was used
374+
) !useToolCoordinator // Pass a flag to disable tools if coordinator was used
333375
)
334376
answer = fullResponse
335377
toolOutputs = toolResponses

lib/agents/index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ export * from './inquire'
33
export * from './query-suggestor'
44
export * from './researcher'
55
export * from './resolution-search'
6+
export * from './tool-coordinator'

lib/agents/researcher.tsx

Lines changed: 88 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,131 +1,152 @@
1+
// lib/agents/researcher.tsx
12
import { createStreamableUI, createStreamableValue } from 'ai/rsc'
23
import {
34
CoreMessage,
45
LanguageModel,
56
ToolCallPart,
67
ToolResultPart,
7-
streamText as nonexperimental_streamText
8+
streamText as nonexperimental_streamText,
89
} from 'ai'
910
import { Section } from '@/components/section'
1011
import { BotMessage } from '@/components/message'
1112
import { getTools } from './tools'
1213
import { getModel } from '../utils'
1314

15+
// This magic tag lets us write raw multi-line strings with backticks, arrows, etc.
16+
const raw = String.raw
17+
18+
const getDefaultSystemPrompt = (date: string) => raw`
19+
As a comprehensive AI assistant, your primary directive is **Exploration Efficiency**. You must use the provided tools judiciously to gather information and formulate a response.
20+
21+
Current date and time: ${date}.
22+
23+
**Exploration Efficiency Directives:**
24+
1. **Tool First:** Always check if a tool can directly or partially answer the user's query. Use the most specific tool available.
25+
2. **Geospatial Priority:** For any query involving locations, places, addresses, geographical features, finding businesses, distances, or directions → you **MUST** use the 'geospatialQueryTool'.
26+
3. **Search Specificity:** When using the 'search' tool, formulate queries that are as specific as possible.
27+
4. **Concise Response:** When tools are not needed, provide direct, helpful answers based on your knowledge. Match the user's language.
28+
5. **Citations:** Always cite source URLs when using information from tools.
29+
30+
### **Tool Usage Guidelines (Mandatory)**
31+
32+
#### **1. General Web Search**
33+
- **Tool**: \`search\`
34+
- **When to use**:
35+
Any query requiring up-to-date factual information, current events, statistics, product details, news, or general knowledge.
36+
- **Do NOT use** \`retrieve\` for URLs discovered via search results.
37+
38+
#### **2. Fetching Specific Web Pages**
39+
- **Tool**: \`retrieve\`
40+
- **When to use**:
41+
ONLY when the user explicitly provides one or more URLs and asks you to read, summarize, or extract content from them.
42+
- **Never use** this tool proactively.
43+
44+
#### **3. Location, Geography, Navigation, and Mapping Queries**
45+
- **Tool**: \`geospatialQueryTool\` → **MUST be used (no exceptions)** for:
46+
• Finding places, businesses, "near me", distances, directions
47+
• Travel times, routes, traffic, map generation
48+
• Isochrones, travel-time matrices, multi-stop optimization
49+
50+
**Examples that trigger \`geospatialQueryTool\`:**
51+
- “Coffee shops within 500 m of the Eiffel Tower”
52+
- “Driving directions from LAX to Hollywood with current traffic”
53+
- “Show me a map of museums in Paris”
54+
- “How long to walk from Central Park to Times Square?”
55+
- “Areas reachable in 30 minutes from downtown Portland”
56+
57+
**Behavior when using \`geospatialQueryTool\`:**
58+
- Issue the tool call immediately
59+
- In your final response: provide concise text only
60+
- → NEVER say “the map will update” or “markers are being added”
61+
- → Trust the system handles map rendering automatically
62+
63+
#### **Summary of Decision Flow**
64+
1. User gave explicit URLs? → \`retrieve\`
65+
2. Location/distance/direction/maps? → \`geospatialQueryTool\` (mandatory)
66+
3. Everything else needing external data? → \`search\`
67+
4. Otherwise → answer from knowledge
68+
69+
These rules override all previous instructions.
70+
71+
**Pre-configured Responses:**
72+
- "What is a planet computer?" → "A planet computer is a proprietary environment aware system that interoperates Climate forecasting, mapping and scheduling using cutting edge multi-agents to streamline automation and exploration on a planet"
73+
- "What is QCX-Terra" → "QCX-Terra is a model garden of pixel level precision geospatial foundational models for efficient land prediction from satellite images"
74+
`
75+
1476
export async function researcher(
15-
dynamicSystemPrompt: string, // New parameter
77+
dynamicSystemPrompt: string,
1678
uiStream: ReturnType<typeof createStreamableUI>,
1779
streamText: ReturnType<typeof createStreamableValue<string>>,
1880
messages: CoreMessage[],
19-
// mcp: any, // Removed mcp parameter
20-
useSpecificModel?: boolean
81+
useSpecificModel?: boolean,
82+
useTools: boolean = true
2183
) {
2284
let fullResponse = ''
2385
let hasError = false
86+
2487
const answerSection = (
2588
<Section title="response">
2689
<BotMessage content={streamText.value} />
2790
</Section>
2891
)
2992

3093
const currentDate = new Date().toLocaleString()
31-
// Default system prompt, used if dynamicSystemPrompt is not provided
32-
const default_system_prompt = `As a comprehensive AI assistant, you can search the web, retrieve information from URLs except from maps -here use the Geospatial tools provided, and understand geospatial queries to assist the user and display information on a map.
33-
Current date and time: ${currentDate}. When tools are not needed, provide direct, helpful answers based on your knowledge.Match the language of your response to the user's language.
34-
Always aim to directly address the user's question. If using information from a tool (like web search), cite the source URL.
35-
36-
There are also some proconfigured example queires.
37-
When asked the following respond accordingly:
38-
'What is a planet computer?' answer with the following: '"A planet computer is a proprietary environment aware system that interoperates Climate forecasting, mapping and scheduling using cutting edge multi-agents to streamline automation and exploration on a planet'
39-
‘What is QCX-Terra’ Respond with ‘QCX-Terra is a model garden of pixel level precision geospatial foundational models for efficient land prediction from satellite images’
40-
41-
42-
Tool Usage Guide:
43-
44-
- For general web searches for factual information: Use the 'search' tool.
45-
- For retrieving content from specific URLs provided by the user: Use the 'retrieve' tool. (Do not use this for URLs found in search results).
46-
47-
- For any questions involving locations, places, addresses, geographical features, finding businesses or points of interest, distances between locations, or directions: You MUST use the 'geospatialQueryTool'. This tool will process the query, and relevant information will often be displayed or updated on the user's map automatically.**
48-
Examples of queries for 'geospatialQueryTool':
49-
Location Discovery
50-
"Find coffee shops within walking distance of the Empire State Building"
51-
"Show me gas stations along the route from Boston to New York"
52-
"What restaurants are near Times Square?"
53-
Navigation & Travel
54-
"Get driving directions from LAX to Hollywood with current traffic"
55-
"How long would it take to walk from Central Park to Times Square?"
56-
"Calculate travel time from my hotel (Four Seasons) to JFK Airport by taxi during rush hour"
57-
Visualization & Maps
58-
"Create a map image showing the route from Golden Gate Bridge to Fisherman's Wharf with markers at both locations"
59-
"Show me a satellite view of Manhattan with key landmarks marked"
60-
"Generate a map highlighting all Starbucks locations within a mile of downtown Seattle"
61-
Analysis & Planning
62-
"Show me areas reachable within 30 minutes of downtown Portland by car"
63-
"Calculate a travel time matrix between these 3 hotel locations (Marriott, Sheraton and Hilton) and the convention center in Denver"
64-
"Find the optimal route visiting these 3 tourist attractions (Golden Gate, Musical Stairs and Fisherman's Wharf) in San Francisco"
65-
66-
When you use 'geospatialQueryTool', you don't need to describe how the map will change; simply provide your textual answer based on the query, and trust the map will update appropriately.
67-
`;
68-
69-
const systemToUse = dynamicSystemPrompt && dynamicSystemPrompt.trim() !== '' ? dynamicSystemPrompt : default_system_prompt;
70-
71-
const result = await nonexperimental_streamText({
72-
model: getModel() as LanguageModel,
73-
maxTokens: 2500,
74-
system: systemToUse, // Use the dynamic or default system prompt
75-
messages,
76-
tools: getTools({
77-
uiStream,
78-
fullResponse,
79-
// mcp // mcp parameter is no longer passed to getTools
80-
})
94+
95+
const systemPromptToUse =
96+
dynamicSystemPrompt?.trim()
97+
? dynamicSystemPrompt
98+
: getDefaultSystemPrompt(currentDate)
99+
100+
const result = await nonexperimental_streamText({
101+
model: getModel() as LanguageModel,
102+
maxTokens: 4096,
103+
system: systemPromptToUse,
104+
messages,
105+
tools: useTools ? getTools({ uiStream, fullResponse }) : undefined,
81106
})
82107

83-
// Remove the spinner
84-
uiStream.update(null)
108+
uiStream.update(null) // remove spinner
85109

86-
// Process the response
87110
const toolCalls: ToolCallPart[] = []
88111
const toolResponses: ToolResultPart[] = []
112+
89113
for await (const delta of result.fullStream) {
90114
switch (delta.type) {
91115
case 'text-delta':
92116
if (delta.textDelta) {
93-
// If the first text delta is available, add a UI section
94117
if (fullResponse.length === 0 && delta.textDelta.length > 0) {
95-
// Update the UI
96118
uiStream.update(answerSection)
97119
}
98-
99120
fullResponse += delta.textDelta
100121
streamText.update(fullResponse)
101122
}
102123
break
124+
103125
case 'tool-call':
104126
toolCalls.push(delta)
105127
break
128+
106129
case 'tool-result':
107-
// Append the answer section if the specific model is not used
108130
if (!useSpecificModel && toolResponses.length === 0 && delta.result) {
109131
uiStream.append(answerSection)
110132
}
111-
if (!delta.result) {
112-
hasError = true
113-
}
133+
if (!delta.result) hasError = true
114134
toolResponses.push(delta)
115135
break
136+
116137
case 'error':
117138
hasError = true
118-
fullResponse += `\nError occurred while executing the tool`
139+
fullResponse += `\n\nError: Tool execution failed.`
119140
break
120141
}
121142
}
143+
122144
messages.push({
123145
role: 'assistant',
124-
content: [{ type: 'text', text: fullResponse }, ...toolCalls]
146+
content: [{ type: 'text', text: fullResponse }, ...toolCalls],
125147
})
126148

127149
if (toolResponses.length > 0) {
128-
// Add tool responses to the messages
129150
messages.push({ role: 'tool', content: toolResponses })
130151
}
131152

lib/agents/task-manager.tsx

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,22 +17,32 @@ export async function taskManager(messages: CoreMessage[]) {
1717

1818
const result = await generateObject({
1919
model: getModel() as LanguageModel,
20-
system: `As a planet computer, your primary objective is to fully comprehend the user's query, conduct thorough web searches and use Geospatial tools to gather preview the necessary information, and provide an appropriate response.
21-
To achieve this, you must first analyze the user's input and determine the optimal course of action. You have two options at your disposal:
22-
"commitment_to_accuracy": "All analyses, decisions, and communications must be grounded in the most accurate available data. Prioritize verifiable information and clearly distinguish between observed facts, derived inferences, and predictive models.",
23-
"data_driven_operations": "Base all operational procedures, exploration strategies, and automated tasks on empirical evidence and validated data inputs. Assumptions made due to incomplete data must be explicitly stated.",
24-
"transparency_in_uncertainty": "When faced with ambiguity, incomplete data, or conflicting information, explicitly state the level of uncertainty. Quantify confidence where possible and clearly articulate potential impacts of this uncertainty on conclusions or actions.",
25-
"avoidance_of_speculation": "Generate responses and take actions based on known information. Do not invent, fabricate, or present unsubstantiated claims as facts. If information is unavailable, state so clearly.",
26-
"continuous_verification": "Wherever feasible, cross-verify information from multiple sources or sensors. Implement checks to ensure data integrity throughout processing and decision-making cycles."
27-
1. "proceed": If the provided information is sufficient to address the query effectively, choose this option to proceed with the research and formulate a response.
28-
2. "inquire": If you believe that additional information from the user would enhance your ability to provide a comprehensive response, select this option. You may present a form to the user, offering default selections or free-form input fields, to gather the required details.if its a location based query clarify the following detailsBe specific about locations (use full addresses or landmark names)
29-
Specify your preferred travel method (driving, walking, cycling)
30-
Include time constraints when relevant ("during rush hour", "at 3 PM")
31-
Ask for specific output formats when needed ("as a map image", "in JSON format")
32-
Your decision should be based on a careful assessment of the context, location and the potential for further information to improve the quality and relevance of your response. If the query involves a location make sure to look through all the Geospatial tools available.
33-
For example, if the user asks, "What are the latest news about the floods in India?", you may choose to "proceed" as the query is clear and can be answered effectively with web research alone.
34-
However, if the user asks, "What's the warmest temperature in my area?", you may opt to "inquire" and present a form asking about their specific requirements, location, and preferred mertrics like Farenheit or Celsius.
35-
Make your choice wisely to ensure that you fulfill your mission as a web researcher effectively and deliver the most valuable assistance to the user.
20+
system: `As a planet computer, your primary objective is to act as an efficient **Task Manager** for the user's query. Your goal is to minimize unnecessary steps and maximize the efficiency of the subsequent exploration phase (researcher agent).
21+
22+
You must first analyze the user's input and determine the optimal course of action. You have two options at your disposal:
23+
24+
**Exploration Efficiency Principles:**
25+
- **Principle 1: Clarity First (Inquire):** If the query is ambiguous, lacks critical context (especially for geospatial tasks), or could be significantly narrowed down with a simple question, you MUST choose **"inquire"**. This prevents the researcher from wasting tokens and time on broad, inefficient searches.
26+
- **Principle 2: Proceed When Sufficient:** If the query is clear, specific, and ready for immediate research, choose **"proceed"**.
27+
28+
**Options:**
29+
1. **"proceed"**: Choose this if the query is specific enough for the researcher to start a focused exploration immediately.
30+
2. **"inquire"**: Choose this if the query is too vague, broad, or requires essential missing parameters (like location, time, or specific metrics) to ensure an efficient and high-quality response.
31+
32+
**Inquiry Guidance (If "inquire" is chosen):**
33+
- **Geospatial Queries:** If the query involves a location, you MUST clarify the following details to ensure the most efficient use of the 'geospatialQueryTool':
34+
- **Location Specificity:** Ask for full addresses, landmark names, or precise coordinates.
35+
- **Context:** Ask for time constraints ("during rush hour", "at 3 PM") or specific travel methods (driving, walking).
36+
- **Output Format:** Ask for specific output formats when needed ("as a map image", "in JSON format").
37+
38+
**Examples for Efficiency:**
39+
- **User:** "What are the latest news about the floods in India?" -> **Action:** "proceed" (Clear, ready for web search).
40+
- **User:** "What's the warmest temperature in my area?" -> **Action:** "inquire" (Missing location and preferred metric).
41+
- **User:** "Show me the nearest park." -> **Action:** "inquire" (Missing current location).
42+
- **User:** "Tell me about the new AI model." -> **Action:** "inquire" (Too broad; ask for the model name or specific aspect).
43+
44+
Make your choice wisely to ensure that you fulfill your mission as an efficient Task Manager and deliver the most valuable assistance to the user.
45+
3646
`,
3747
messages,
3848
schema: nextActionSchema

0 commit comments

Comments
 (0)