Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
7 changes: 4 additions & 3 deletions app/actions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -103,23 +103,24 @@ async function submit(formData?: FormData, skip?: boolean) {
try {
const streamResult = await resolutionSearch(messages, timezone, drawnFeatures, location);

let partialObject: any;
let fullSummary = '';
for await (const partialObject of streamResult.partialObjectStream) {
for await (partialObject of streamResult.partialObjectStream) {
if (partialObject.summary) {
fullSummary = partialObject.summary;
summaryStream.update(fullSummary);
}
}

const analysisResult = await streamResult.object;
const analysisResult: any = await streamResult.object;
summaryStream.done(analysisResult.summary || 'Analysis complete.');

// Reconstruct standard GeoJSON from flattened schema if present
let geoJson: FeatureCollection | null = null;
if (analysisResult.geoJson && analysisResult.geoJson.features) {
geoJson = {
type: 'FeatureCollection',
features: analysisResult.geoJson.features.map(f => ({
features: analysisResult.geoJson.features.map( (f: any) => ({
type: 'Feature',
geometry: {
type: f.geometryType as any,
Expand Down
1,421 changes: 958 additions & 463 deletions bun.lock

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions components/map/mapbox-map.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ export const Mapbox: React.FC<{ position?: { latitude: number; longitude: number
map.current.off('draw.create', updateMeasurementLabels)
map.current.off('draw.delete', updateMeasurementLabels)
map.current.off('draw.update', updateMeasurementLabels)
map.current.removeControl(drawRef.current)
map.current.removeControl(drawRef.current as any)
drawRef.current = null

// Clean up any existing labels
Expand Down Expand Up @@ -282,7 +282,7 @@ export const Mapbox: React.FC<{ position?: { latitude: number; longitude: number
})

// Add control to map
map.current.addControl(drawRef.current, 'top-right')
map.current.addControl(drawRef.current as any, 'top-right')

// Add navigation control only on desktop
if (window.innerWidth > 768) {
Expand Down Expand Up @@ -509,7 +509,7 @@ export const Mapbox: React.FC<{ position?: { latitude: number; longitude: number
map.current.off('draw.create', updateMeasurementLabels)
map.current.off('draw.delete', updateMeasurementLabels)
map.current.off('draw.update', updateMeasurementLabels)
map.current.removeControl(drawRef.current)
map.current.removeControl(drawRef.current as any)
drawRef.current = null

// Clean up any existing labels
Expand Down
3 changes: 2 additions & 1 deletion components/message.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,14 @@ export function BotMessage({ content }: { content: StreamableValue<string> }) {

return (
<div className="overflow-x-auto">
<div className="prose-sm prose-neutral prose-a:text-accent-foreground/50">
<MemoizedReactMarkdown
rehypePlugins={[[rehypeExternalLinks, { target: '_blank' }], rehypeKatex]}
remarkPlugins={[remarkGfm, remarkMath]}
className="prose-sm prose-neutral prose-a:text-accent-foreground/50"
>
{processedData}
</MemoizedReactMarkdown>
</div>
</div>
)
}
Expand Down
2 changes: 1 addition & 1 deletion components/theme-provider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import * as React from 'react'
import { ThemeProvider as NextThemesProvider } from 'next-themes'
import { type ThemeProviderProps } from 'next-themes/dist/types'
import { type ThemeProviderProps } from 'next-themes'

export function ThemeProvider({ children, ...props }: ThemeProviderProps) {
return <NextThemesProvider {...props}>{children}</NextThemesProvider>
Expand Down
3 changes: 1 addition & 2 deletions components/ui/markdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,5 @@ import ReactMarkdown, { Options } from 'react-markdown'
export const MemoizedReactMarkdown: FC<Options> = memo(
ReactMarkdown,
(prevProps, nextProps) =>
prevProps.children === nextProps.children &&
prevProps.className === nextProps.className
prevProps.children === nextProps.children
Comment on lines 6 to +7

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify where MemoizedReactMarkdown is used and whether non-children props vary.
rg -n -C3 '\bMemoizedReactMarkdown\b'
rg -n -C3 '<MemoizedReactMarkdown[^>]*className=|<MemoizedReactMarkdown[^>]*components=|<MemoizedReactMarkdown[^>]*remarkPlugins=|<MemoizedReactMarkdown[^>]*rehypePlugins='

Repository: QueueLab/QCX

Length of output: 1627


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== components/ui/markdown.tsx (lines 1-120) ==="
nl -ba components/ui/markdown.tsx | sed -n '1,120p'

echo "=== components/message.tsx (around MemoizedReactMarkdown usage) ==="
nl -ba components/message.tsx | sed -n '1,120p'

Repository: QueueLab/QCX

Length of output: 166


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== components/ui/markdown.tsx (first 160 lines) ==="
cat -n components/ui/markdown.tsx | sed -n '1,160p'

echo "=== components/message.tsx (first 220 lines) ==="
cat -n components/message.tsx | sed -n '1,220p'

Repository: QueueLab/QCX

Length of output: 2287


🏁 Script executed:

#!/bin/bash
set -euo pipefail

rg -n "MemoizedReactMarkdown" -S

Repository: QueueLab/QCX

Length of output: 332


Custom memo comparator only checks children—brittle for future props, but not a current issue here.

MemoizedReactMarkdown is only used in components/message.tsx, and that call site always passes the same remarkPlugins/rehypePlugins values (even though the arrays/options are re-created each render). Since markdown content changes drive children, the component still updates when needed. The main risk is for future call sites where non-children props change while children stays the same; in that case this comparator could suppress updates. Consider removing the custom comparator or using a comparator that accounts for the relevant props.

🤖 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 `@components/ui/markdown.tsx` around lines 6 - 7, The custom memo comparator
currently used for MemoizedReactMarkdown only compares prevProps.children ===
nextProps.children which can suppress updates if other props change; update the
memo usage by either removing the custom comparator so React.memo uses default
shallow prop comparison, or replace the comparator with a shallow equality that
also checks remarkPlugins and rehypePlugins (and any other passed props) by
comparing prevProps.remarkPlugins === nextProps.remarkPlugins &&
prevProps.rehypePlugins === nextProps.rehypePlugins && prevProps.children ===
nextProps.children; locate the memo wrapper around the ReactMarkdown component
(the function using (prevProps, nextProps) => prevProps.children ===
nextProps.children and the exported MemoizedReactMarkdown) and apply one of
these fixes.

)
2 changes: 1 addition & 1 deletion lib/actions/suggest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export async function getSuggestions(

;(async () => {
const result = await streamObject({
model: (await getModel()) as LanguageModel,
model: (await getModel()) as any,
system: systemPrompt,
messages: [{ role: 'user', content: query }],
schema: relatedSchema
Expand Down
2 changes: 1 addition & 1 deletion lib/agents/inquire.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export async function inquire(

let finalInquiry: PartialInquiry = {};
const result = await streamObject({
model: (await getModel()) as LanguageModel,
model: (await getModel()) as any,
system: `You are a helpful assistant that gathers clarifying information from the user.
Generate a structured inquiry with a clear question, multiple choice options, and optionally allow free-text input.
Ensure the inquiry is concise and helps narrow down the user's intent.`,
Expand Down
2 changes: 1 addition & 1 deletion lib/agents/query-suggestor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export async function querySuggestor(

// OPTIMIZATION: Use a more concise system prompt to reduce token usage
const result = await streamObject({
model: (await getModel()) as LanguageModel,
model: (await getModel()) as any,
system: `Generate 3 follow-up queries that explore the subject matter deeper. Format as JSON with an "items" array containing objects with "query" fields. Keep queries concise and relevant.`,
messages,
schema: relatedSchema,
Expand Down
2 changes: 1 addition & 1 deletion lib/agents/researcher.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ export async function researcher(
})

const result = await nonexperimental_streamText({
model: (await getModel(hasImage)) as LanguageModel,
model: (await getModel(hasImage)) as any,
maxTokens: 4096,
system: systemPromptToUse,
messages,
Expand Down
2 changes: 1 addition & 1 deletion lib/agents/resolution-search.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ Analyze the user's prompt and the image to provide a holistic understanding of t

// Use streamObject to get partial results.
return streamObject({
model: await getModel(hasImage),
model: (await getModel(hasImage)) as any,
system: systemPrompt,
messages: filteredMessages,
schema: resolutionSearchSchema,
Expand Down
2 changes: 1 addition & 1 deletion lib/agents/task-manager.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export async function taskManager(messages: CoreMessage[]) {
}

const result = await generateObject({
model: (await getModel()) as LanguageModel,
model: (await getModel()) as any,
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).

You must first analyze the user's input and determine the optimal course of action. You have two options at your disposal:
Expand Down
2 changes: 1 addition & 1 deletion lib/agents/writer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export async function writer(
const systemToUse = dynamicSystemPrompt && dynamicSystemPrompt.trim() !== '' ? dynamicSystemPrompt : default_system_prompt;

const result = await nonexperimental_streamText({
model: (await getModel()) as LanguageModel,
model: (await getModel()) as any,
maxTokens: 2500,
system: systemToUse, // Use the dynamic or default system prompt
messages
Expand Down
3 changes: 2 additions & 1 deletion lib/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ export async function getModel(requireVision: boolean = false) {

if (awsAccessKeyId && awsSecretAccessKey) {
const bedrock = createAmazonBedrock({
// @ts-ignore
bedrockOptions: {
region: awsRegion,
credentials: {
Expand All @@ -113,7 +114,7 @@ export async function getModel(requireVision: boolean = false) {
},
},
});
const model = bedrock(bedrockModelId, {
const model = (bedrock as any)(bedrockModelId, {
additionalModelRequestFields: { top_k: 350 },
});
return model;
Expand Down
99 changes: 50 additions & 49 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,89 +16,90 @@
"test:e2e:debug": "playwright test --debug"
},
"dependencies": {
"@ai-sdk/amazon-bedrock": "^1.1.6",
"@ai-sdk/anthropic": "^1.2.12",
"@ai-sdk/google": "^1.2.22",
"@ai-sdk/openai": "^1.3.24",
"@ai-sdk/xai": "^1.2.18",
"@composio/core": "^0.3.3",
"@google-cloud/storage": "^7.18.0",
"@ai-sdk/amazon-bedrock": "^4.0.113",
"@ai-sdk/anthropic": "^3.0.81",
"@ai-sdk/google": "^3.0.80",
"@ai-sdk/openai": "^3.0.68",
"@ai-sdk/xai": "^3.0.93",
"@composio/core": "^0.10.0",
"@google-cloud/storage": "^7.19.0",
"@google/generative-ai": "^0.24.1",
"@heroicons/react": "^2.2.0",
"@hookform/resolvers": "3.3.4",
"@mapbox/mapbox-gl-draw": "^1.5.0",
"@modelcontextprotocol/sdk": "^1.13.0",
"@radix-ui/react-alert-dialog": "^1.1.10",
"@radix-ui/react-avatar": "^1.1.6",
"@radix-ui/react-checkbox": "^1.2.2",
"@radix-ui/react-collapsible": "^1.1.7",
"@radix-ui/react-dialog": "^1.1.10",
"@radix-ui/react-dropdown-menu": "^2.1.11",
"@radix-ui/react-label": "^2.1.4",
"@radix-ui/react-radio-group": "^1.3.4",
"@radix-ui/react-separator": "^1.1.4",
"@radix-ui/react-slider": "^1.3.2",
"@radix-ui/react-slot": "^1.2.0",
"@radix-ui/react-switch": "^1.2.2",
"@mapbox/mapbox-gl-draw": "^1.5.1",
"@modelcontextprotocol/sdk": "^1.29.0",
"@radix-ui/react-alert-dialog": "^1.1.16",
"@radix-ui/react-avatar": "^1.1.12",
"@radix-ui/react-checkbox": "^1.3.4",
"@radix-ui/react-collapsible": "^1.1.13",
"@radix-ui/react-dialog": "^1.1.16",
"@radix-ui/react-dropdown-menu": "^2.1.17",
"@radix-ui/react-label": "^2.1.9",
"@radix-ui/react-radio-group": "^1.4.0",
"@radix-ui/react-separator": "^1.1.9",
"@radix-ui/react-slider": "^1.4.0",
"@radix-ui/react-slot": "^1.2.5",
"@radix-ui/react-switch": "^1.3.0",
"@radix-ui/react-tabs": "^1.1.9",
"@radix-ui/react-toast": "^1.2.11",
"@radix-ui/react-tooltip": "^1.2.3",
"@supabase/ssr": "^0.3.0",
"@supabase/supabase-js": "^2.0.0",
"@radix-ui/react-tooltip": "^1.2.9",
"@supabase/ssr": "^0.10.3",
"@supabase/supabase-js": "^2.107.0",
"@tailwindcss/typography": "^0.5.16",
"@tavily/core": "^0.6.4",
"@turf/turf": "^7.2.0",
"@tavily/core": "^0.7.5",
"@turf/turf": "^7.3.5",
"@types/mapbox__mapbox-gl-draw": "^1.4.8",
"@types/pg": "^8.15.4",
"@upstash/redis": "^1.35.0",
"@vercel/analytics": "^1.5.0",
"@vercel/speed-insights": "^1.2.0",
"@vis.gl/react-google-maps": "^1.7.1",
"ai": "^4.3.19",
"@upstash/redis": "^1.38.0",
"@vercel/analytics": "^2.0.1",
"@vercel/speed-insights": "^2.0.0",
"@vis.gl/react-google-maps": "^1.8.3",
"ai": "4.3.19",
"build": "^0.1.4",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"cookie": "^0.6.0",
"cookie": "^1.1.1",
"csv-parse": "^6.1.0",
"dotenv": "^16.5.0",
"drizzle-kit": "^0.31.1",
"drizzle-orm": "^0.29.0",
"drizzle-orm": "^0.45.2",
"embla-carousel-react": "^8.6.0",
"exa-js": "^1.6.13",
"framer-motion": "^12.23.24",
"geotiff": "^2.1.4-beta.1",
"exa-js": "^2.13.0",
"framer-motion": "^12.40.0",
"geotiff": "^3.0.5",
"glassmorphic": "^0.0.3",
"html2canvas": "^1.4.1",
"jspdf": "^4.2.1",
"katex": "^0.16.22",
"katex": "^0.17.0",
"lodash": "^4.17.21",
"lottie-react": "^2.4.1",
"lucide-react": "^0.507.0",
"mapbox-gl": "^3.11.0",
"next": "15.3.8",
"next-themes": "^0.3.0",
"lucide-react": "^1.17.0",
"mapbox-gl": "^3.24.0",
"nanoid": "^5.1.11",
"next": "^16.2.7",
"next-themes": "^0.4.6",
"open-codex": "^0.1.30",
"pg": "^8.16.2",
"pg": "^8.21.0",
"proj4": "^2.20.2",
"radix-ui": "^1.3.4",
"react": "19.1.2",
"react-dom": "19.1.2",
"react": "^19.2.7",
"react-dom": "^19.2.7",
"react-hook-form": "^7.56.2",
"react-icons": "^5.5.0",
"react-markdown": "^9.1.0",
"react-markdown": "^10.1.0",
"react-textarea-autosize": "^8.5.9",
"react-toastify": "^10.0.6",
"rehype-external-links": "^3.0.0",
"rehype-katex": "^7.0.1",
"remark-gfm": "^4.0.1",
"remark-math": "^6.0.0",
"sonner": "^1.7.4",
"tailwind-merge": "^2.6.0",
"sonner": "^2.0.7",
"tailwind-merge": "^3.6.0",
"tailwindcss-animate": "^1.0.7",
"tz-lookup": "^6.1.25",
"use-mcp": "^0.0.9",
"use-mcp": "^0.0.21",
"uuid": "^9.0.0",
"zod": "^3.25.0",
"zod": "^4.4.3",
"zustand": "^5.0.9"
},
"devDependencies": {
Expand Down
Binary file modified server.log
Binary file not shown.
5 changes: 3 additions & 2 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"jsx": "react-jsx",
"incremental": true,
"plugins": [
{
Expand All @@ -32,7 +32,8 @@
"next-env.d.ts",
"**/*.ts",
"**/*.tsx",
".next/types/**/*.ts"
".next/types/**/*.ts",
".next/dev/types/**/*.ts"
],
"exclude": [
"node_modules"
Expand Down