Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 75 additions & 0 deletions NEXTJS_GEMINI_RESEARCH_REPORT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# Next.js 16 & Gemini 3.1: Strategic Advancement Report (May 2026)

## Executive Summary
This report details the latest advancements in the **Next.js 16** framework and the **Gemini 3.1 Pro** AI model. Based on the current QCX platform architecture (Next.js 15.3, React 19.1, Gemini 3.1 Pro Preview), several high-impact upgrade opportunities have been identified to enhance performance, reasoning capabilities, and agentic workflows.

---

## 1. Next.js 16: The Routing & Performance Overhaul

Next.js 16 (released May 2026) introduces a fundamental shift in how applications handle navigation and data prefetching [1].

### Key Advancements
| Feature | Description | Impact for QCX |
| :--- | :--- | :--- |
| **Routing Overhaul** | Complete rewrite of the navigation system for leaner, faster transitions. | Faster map-to-chat transitions and smoother UI. |
| **Layout Deduplication** | Shared layouts are downloaded only once during prefetching across multiple URLs. | Reduced bandwidth and faster multi-page navigation. |
| **Incremental Prefetching** | Only fetches missing cache segments instead of entire pages. | Significant reduction in total transfer size for complex dashboards. |
| **Stable Turbopack** | Turbopack is now the default for both `dev` and `build` without experimental flags. | Faster development cycles and optimized production builds. |
| **React 19.2 Support** | Native support for View Transitions, `useEffectEvent`, and Activity. | Enhanced animation capabilities for the geospatial UI. |
| **React Compiler** | Automatic memoization of components for performance gains. | Eliminates manual `useMemo`/`useCallback` overhead in complex components. |

### Upgrade Recommendations for QCX
1. **Migrate to Next.js 16**: Update `package.json` to `next@16.x`.
2. **Leverage Cache Components**: Replace `experimental.dynamicIO` with the new `cacheComponents` configuration for granular server-side caching.
3. **Adopt React Compiler**: Enable the React Compiler to automatically optimize the heavy geospatial UI components.
4. **Rename Middleware**: Rename `middleware.ts` to `proxy.ts` to align with the new Node.js runtime standards in v16.

---

## 2. Gemini 3.1 Pro: Reasoning & Agentic Excellence

Gemini 3.1 Pro (released February 2026) is a reasoning-optimized upgrade that excels in complex, multi-step task execution [2].

### Key Advancements
| Capability | Gemini 3.1 Pro Performance | Strategic Advantage |
| :--- | :--- | :--- |
| **Abstract Reasoning** | **77.1%** on ARC-AGI-2 (leads all models) [2]. | Superior handling of complex geospatial logic and land classification. |
| **Agentic Workflows** | **33.5%** on APEX-Agents (nearly 2x Gemini 3 Pro) [2]. | Highly reliable multi-step tool use for the `researcher` and `taskManager`. |
| **Custom Tools Endpoint** | New `gemini-3.1-pro-preview-customtools` endpoint. | Optimized specifically for bash, terminal, and custom API tool calls. |
| **Expert Science** | **94.3%** on GPQA Diamond [2]. | Enhanced accuracy for technical geospatial and environmental analysis. |
| **Context Caching** | Native support for long-context caching. | Drastically reduces costs for long-running chat sessions with large histories. |

### Integration Recommendations for QCX
1. **Switch to Custom Tools Endpoint**: For the `researcher` agent, use the `gemini-3.1-pro-preview-customtools` endpoint to improve tool-calling reliability.
2. **Implement Context Caching**: Use context caching for the `resolutionSearch` agent when analyzing large satellite imagery datasets or long conversation histories.
3. **Reasoning-First Prompts**: Update system prompts to leverage the improved chain-of-thought reasoning for complex land feature predictions.
4. **Batch API Usage**: Utilize the new Batch API for non-real-time geospatial analysis to reduce costs by up to 50%.

---

## 3. QCX Platform: Strategic Update Roadmap

### Phase 1: Core Infrastructure (Immediate)
* **Upgrade to Next.js 16.2+**: Gain the routing overhaul and stable Turbopack benefits.
* **Update React to 19.2**: Enable View Transitions for the map interface.
* **Enable React Compiler**: Optimize the `Copilot` and `SearchRelated` components automatically.

### Phase 2: AI Intelligence (Short-term)
* **Transition to `customtools` Endpoint**: Improve the reliability of the `geospatialQueryTool`.
* **Implement Context Caching**: Optimize token usage for the `researcher` agent.
* **Refine Reasoning Prompts**: Update the `resolutionSearch` system prompt to utilize the 77.1% ARC-AGI-2 reasoning capabilities.

### Phase 3: Performance & UX (Mid-term)
* **Adopt Incremental Prefetching**: Optimize the loading of the search results page.
* **Implement View Transitions**: Create seamless transitions between the map view and the chat panel.
* **Leverage Build Adapters**: Optimize the standalone Docker build process for faster deployments.

---

## Conclusion
The combination of **Next.js 16's routing efficiency** and **Gemini 3.1 Pro's reasoning power** provides a significant competitive advantage for the QCX platform. By following this roadmap, the platform will achieve superior UI responsiveness and industry-leading AI analysis accuracy.

## References
[1] [Upgrading: Version 16 | Next.js](https://nextjs.org/docs/app/guides/upgrading/version-16)
[2] [Gemini 3.1 Pro: #1 Reasoning AI Benchmarks & API Guide | Google DeepMind](https://vertu.com/ai-tools/gemini-3-1-pro-benchmarks-api-specs-developer-guide-in-2026/)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Reference [2] uses a non-authoritative source for benchmark claims.

vertu.com is a luxury smartphone brand, not an official Google or DeepMind publication. All benchmark figures cited in the Gemini 3.1 Pro table (ARC-AGI-2, APEX-Agents, GPQA Diamond) trace back to this single non-authoritative reference. Replace with the official Google DeepMind blog post or the Gemini API models documentation.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@NEXTJS_GEMINI_RESEARCH_REPORT.md` at line 75, Reference [2] in the Gemini 3.1
Pro benchmarks table cites a non-authoritative source (vertu.com); replace that
citation with the official Google/DeepMind publication or the Gemini API/models
documentation by updating the reference entry for [2] and any in-text citations
in the "Gemini 3.1 Pro" table (the rows for ARC-AGI-2, APEX-Agents, GPQA
Diamond) to point to the official DeepMind blog post or the Gemini API docs;
ensure the new reference URL and title clearly identify Google/DeepMind as the
source and remove or archive the vertu.com link.

17 changes: 15 additions & 2 deletions lib/agents/researcher.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,17 @@ import { DrawnFeature } from './resolution-search'
const raw = String.raw

const getDefaultSystemPrompt = (date: string, drawnFeatures?: DrawnFeature[]) => raw`
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.
As a comprehensive AI assistant, your primary directive is **Exploration Efficiency with Enhanced Reasoning**. You must use the provided tools judiciously to gather information and formulate a response.

Current date and time: ${date}.

**Reasoning Approach (Gemini 3.1 Pro Enhanced):**
Before using any tool, break down complex queries into logical steps:
1. Understand the user's intent and constraints
2. Identify which tool(s) can best address each part
3. Explain your reasoning when selecting between multiple tools
4. Execute tools in the optimal order

Comment on lines +25 to +31
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Same model-identity coupling as in resolution-search.tsx — remove the Gemini brand from the prompt heading.

Line 25's "Reasoning Approach (Gemini 3.1 Pro Enhanced):" heading will be received verbatim by Grok, GPT-5.1, or Bedrock Claude whenever those providers are active. The instruction itself is sound; the brand attribution is the problem.

🛠️ Proposed fix
-**Reasoning Approach (Gemini 3.1 Pro Enhanced):**
+**Reasoning Approach:**
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
**Reasoning Approach (Gemini 3.1 Pro Enhanced):**
Before using any tool, break down complex queries into logical steps:
1. Understand the user's intent and constraints
2. Identify which tool(s) can best address each part
3. Explain your reasoning when selecting between multiple tools
4. Execute tools in the optimal order
**Reasoning Approach:**
Before using any tool, break down complex queries into logical steps:
1. Understand the user's intent and constraints
2. Identify which tool(s) can best address each part
3. Explain your reasoning when selecting between multiple tools
4. Execute tools in the optimal order
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/agents/researcher.tsx` around lines 25 - 31, The prompt heading currently
hardcodes a vendor string "Reasoning Approach (Gemini 3.1 Pro Enhanced):" which
couples the prompt to a specific provider; replace that literal with a
model-agnostic heading such as "Reasoning Approach:" (or "Reasoning Approach
(model-agnostic):") in lib/agents/researcher.tsx wherever that string appears,
and mirror the same change in the other file with the same issue (e.g.,
resolution-search.tsx); ensure no provider brand names are embedded in prompt
strings passed to the agent so the prompts remain provider-agnostic.

${drawnFeatures && drawnFeatures.length > 0 ? `The user has drawn the following features on the map for your reference:
${drawnFeatures.map(f => `- ${f.type} with measurement ${f.measurement}`).join('\n')}
Use these user-drawn areas/lines as primary areas of interest for your analysis if applicable to the query.` : ''}
Expand Down Expand Up @@ -77,6 +84,12 @@ These rules override all previous instructions.
**Pre-configured Responses:**
- "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"
- "What is QCX-Terra" → "QCX-Terra is a model garden of pixel level precision geospatial foundational models for efficient land prediction from satellite images"

**Tool Reasoning Enhancement:**
When selecting tools, consider:
- Geospatial queries benefit from multi-step reasoning before tool invocation
- Complex searches may require breaking down into multiple search queries
- Always explain your tool selection rationale to the user when appropriate
`

export async function researcher(
Expand Down Expand Up @@ -111,7 +124,7 @@ export async function researcher(
)

const result = await nonexperimental_streamText({
model: (await getModel(hasImage)) as LanguageModel,
model: (await getModel(hasImage, true)) as LanguageModel,
maxTokens: 4096,
system: systemPromptToUse,
messages,
Expand Down
28 changes: 19 additions & 9 deletions lib/agents/resolution-search.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,16 @@ export async function resolutionSearch(messages: CoreMessage[], timezone: string
}

const systemPrompt = `
As a geospatial analyst, your task is to analyze the provided satellite image of a geographic location.
As a geospatial analyst with advanced reasoning capabilities (Gemini 3.1 Pro), your task is to analyze the provided satellite image of a geographic location.

**Reasoning Approach (Enhanced Chain-of-Thought):**
Before providing your analysis, break down the task into logical steps:
1. Identify visible features and patterns in the satellite image
2. Classify land types based on spectral and spatial characteristics
3. Extract geographic coordinates and validate against provided data
4. Integrate temporal context (time of day, season) with visual observations
5. Cross-reference with recent news and events for the location
6. Synthesize findings into structured output

**Temporal Context:**
The current local time at this location is ${localTime} (timezone: ${timezone}).
Expand All @@ -154,15 +163,16 @@ The user has drawn the following features on the map for your reference:
${drawnFeatures.map(f => `- ${f.type} (${f.measurement}): ${JSON.stringify(f.geometry)}`).join('\n')}
Use these user-drawn areas/lines as primary areas of interest for your analysis.` : ''}

**Analysis Requirements:**
**Multi-Step Analysis Requirements:**

1. **Land Feature Classification:** Identify and describe the different types of land cover visible in the image (e.g., urban areas, forests, water bodies, agricultural fields).
2. **Points of Interest (POI):** Detect and name any significant landmarks, infrastructure (e.g., bridges, major roads), or notable buildings.
3. **Temporal Analysis:** Consider how the time of day and season might affect what's visible in the image.
4. **Coordinate Extraction:** If possible, confirm or refine the geocoordinates (latitude/longitude) of the center of the image.
5. **COG Applicability:** Determine if this location would benefit from Cloud Optimized GeoTIFF (COG) analysis for high-precision temporal or spectral data.
6. **News Integration:** Reference any recent news or events that may be relevant to the current state of the location.
7. **Structured Output:** Return your findings in a structured JSON format including summary, geoJson, and newsContext.
1. **Abstract Pattern Recognition (ARC-AGI-2 Level):** Look for non-obvious patterns and relationships in the satellite imagery that indicate land use changes or unusual features.
2. **Land Feature Classification:** Systematically identify and describe land cover types (urban, forests, water, agriculture, infrastructure).
3. **Points of Interest (POI):** Detect and name significant landmarks, infrastructure (bridges, roads, buildings), and anomalies.
4. **Temporal Analysis:** Explain how the time of day and season affect visibility and interpretation of features.
5. **Coordinate Extraction:** Confirm or refine geocoordinates with reasoning about image center and reference points.
6. **COG Applicability:** Assess whether this location would benefit from Cloud Optimized GeoTIFF analysis.
7. **News Integration:** Explain how recent events correlate with visible landscape features.
8. **Structured Output:** Return findings in structured JSON format with detailed reasoning.

Your analysis should be based on the visual information in the image, the temporal context provided, and your general knowledge. Do not attempt to access external websites or perform web searches beyond what has been provided.

Expand Down
114 changes: 114 additions & 0 deletions lib/utils/context-cache.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
/**
* Context Caching Utility for Gemini 3.1 Pro
* Reduces token usage for long conversation histories by caching stable context
*/

import { CoreMessage } from 'ai';

interface CachedContext {
conversationId: string;
messageCheckpoint: number;
cachedPrefix: string;
systemPrompt: string;
timestamp: number;
ttl: number; // Time to live in milliseconds
}

const contextCache = new Map<string, CachedContext>();
const CACHE_TTL = 30 * 60 * 1000; // 30 minutes
const MAX_CACHE_SIZE = 100;

/**
* Generate a cache key based on conversation ID and message count
*/
function generateCacheKey(conversationId: string, messageCount: number): string {
return `${conversationId}:${messageCount}`;
}

/**
* Cache conversation context to reduce token usage
*/
export function cacheConversationContext(
conversationId: string,
messages: CoreMessage[],
systemPrompt: string
): void {
const messageCheckpoint = messages.length;
const cacheKey = generateCacheKey(conversationId, messageCheckpoint);

// Create a serialized prefix of the conversation
const cachedPrefix = messages
.slice(0, Math.floor(messages.length * 0.8)) // Cache first 80% of messages
.map(m => `${m.role}: ${typeof m.content === 'string' ? m.content : '[complex content]'}`)
.join('\n');

const cachedContext: CachedContext = {
conversationId,
messageCheckpoint,
cachedPrefix,
systemPrompt,
timestamp: Date.now(),
ttl: CACHE_TTL,
};

contextCache.set(cacheKey, cachedContext);

// Cleanup old entries if cache exceeds max size
if (contextCache.size > MAX_CACHE_SIZE) {
const oldestKey = Array.from(contextCache.entries())
.sort((a, b) => a[1].timestamp - b[1].timestamp)[0][0];
contextCache.delete(oldestKey);
}
}

/**
* Retrieve cached context if available and not expired
*/
export function getCachedContext(
conversationId: string,
messageCount: number
): CachedContext | null {
const cacheKey = generateCacheKey(conversationId, messageCount);
const cached = contextCache.get(cacheKey);

if (!cached) return null;

// Check if cache has expired
if (Date.now() - cached.timestamp > cached.ttl) {
contextCache.delete(cacheKey);
return null;
}

return cached;
}

/**
* Clear cache for a specific conversation
*/
export function clearConversationCache(conversationId: string): void {
const keysToDelete: string[] = [];
for (const [key] of contextCache.entries()) {
if (key.startsWith(conversationId)) {
keysToDelete.push(key);
}
}
keysToDelete.forEach(key => contextCache.delete(key));
}
Comment on lines +88 to +96
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

clearConversationCache has a prefix-collision bug.

key.startsWith(conversationId) will incorrectly delete cache entries belonging to a different conversation whose ID begins with the same substring (e.g., clearing "abc" also clears "abcdef:5"). The separator should be included in the prefix test.

🐛 Proposed fix
-    if (key.startsWith(conversationId)) {
+    if (key.startsWith(conversationId + ':')) {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/utils/context-cache.ts` around lines 88 - 96, clearConversationCache
currently deletes keys using key.startsWith(conversationId), causing collisions
when another conversationId begins with the same prefix; update the check in
clearConversationCache to include the separator used in cache keys (e.g., test
key.startsWith(conversationId + ':') and also allow key === conversationId) so
only the exact conversation namespace (and its children) are removed from
contextCache.


/**
* Clear all cached contexts
*/
export function clearAllContextCache(): void {
contextCache.clear();
}

/**
* Get cache statistics for monitoring
*/
export function getCacheStats() {
return {
size: contextCache.size,
maxSize: MAX_CACHE_SIZE,
ttl: CACHE_TTL,
};
}
8 changes: 5 additions & 3 deletions lib/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export function generateUUID(): string {
*/
export { generateUUID as nanoid };

export async function getModel(requireVision: boolean = false) {
export async function getModel(requireVision: boolean = false, usesTools: boolean = false) {
const selectedModel = await getSelectedModel();

const xaiApiKey = process.env.XAI_API_KEY;
Expand Down Expand Up @@ -57,7 +57,8 @@ export async function getModel(requireVision: boolean = false) {
apiKey: gemini3ProApiKey,
});
try {
return google('gemini-3.1-pro-preview');
const modelId = usesTools ? 'gemini-3.1-pro-preview-customtools' : 'gemini-3.1-pro-preview';
return google(modelId);
} catch (error) {
console.error('Selected model "Gemini 3.1 Pro" is configured but failed to initialize.', error);
throw new Error('Failed to initialize selected model.');
Expand Down Expand Up @@ -85,7 +86,8 @@ export async function getModel(requireVision: boolean = false) {
apiKey: gemini3ProApiKey,
});
try {
return google('gemini-3.1-pro-preview');
const modelId = usesTools ? 'gemini-3.1-pro-preview-customtools' : 'gemini-3.1-pro-preview';
return google(modelId);
} catch (error) {
console.warn('Gemini 3.1 Pro API unavailable, falling back to next provider:', error);
}
Expand Down
10 changes: 10 additions & 0 deletions next.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,16 @@ const nextConfig = {
bodySizeLimit: '200mb',
},
},

// turbopack root at top level in v16
turbopack: {
root: '.',
},

// reactCompiler and cacheComponents moved to top level in v16
reactCompiler: true,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

reactCompiler: true increases build times — test in CI before shipping.

The reactCompiler option has been promoted from experimental to stable in Next.js 16 and is not enabled by default while the team gathers build performance data; enabling it increases compile times in development and builds because the React Compiler relies on Babel.

This is a non-breaking improvement, but confirm the build time increase is acceptable in your CI pipeline.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@next.config.mjs` at line 19, The config enables reactCompiler: true which can
increase build/CI times; run a CI build with reactCompiler set to true (in
next.config.mjs) to measure impact and confirm it's acceptable, and if the build
time regression is unacceptable, revert/remove the reactCompiler: true flag or
gate it behind an environment variable (e.g., process.env.ENABLE_REACT_COMPILER)
so CI can opt-in only after validation.

cacheComponents: true,

transpilePackages: ['QCX', 'mapbox_mcp'], // Added to transpile local packages
};

Expand Down
Loading