feat(ai): extend FluxAI navigation with cross-page routing

The navigate_to_section tool now supports two modes:
A) Same-page scroll — scrollIntoView to real homepage DOM IDs
   (technology, applications-dashboard, applications-deep, global,
   our-story, legacy)
B) Cross-page routing — router.push to /applications/{slug},
   /news, /heritage, /parts with automatic locale prefix.

Fixed: system prompt listed phantom section IDs (hero, news,
heritage, timeline, parts-catalog, contact) that don't exist in
the DOM — causing all non-homepage navigations to silently fail.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-06 19:38:06 -05:00
parent c45a5be99e
commit 95132476ae
2 changed files with 66 additions and 21 deletions
+35 -16
View File
@@ -5,6 +5,7 @@ import { Sparkles, ArrowRight, X, Minus, Database, Maximize2, Minimize2 } from "
import { useChat } from "@ai-sdk/react";
import { DefaultChatTransport, lastAssistantMessageIsCompleteWithToolCalls } from "ai";
import { useUIStore } from "@/lib/store/uiStore";
import { useRouter, usePathname } from "next/navigation";
import { useState, useEffect, useRef, useMemo } from "react";
// ── Renderers ──
@@ -24,6 +25,10 @@ export default function SilentObserver() {
setHighlightedMapNode, setSelectedMarkerId,
} = useUIStore();
const router = useRouter();
const pathname = usePathname();
const locale = pathname?.split('/')[1] || 'en';
const [input, setInput] = useState("");
const [isDark, setIsDark] = useState(false);
const [isWideMode, setIsWideMode] = useState(false);
@@ -68,24 +73,38 @@ export default function SilentObserver() {
if (toolCall.dynamic) return;
if (toolCall.toolName === "navigate_to_section") {
const { section, subAction, tabId, nodeId } = toolCall.input as {
section: string; subAction?: string; tabId?: string; nodeId?: string;
const { section, url, subAction, tabId, nodeId } = toolCall.input as {
section?: string; url?: string; subAction?: string; tabId?: string; nodeId?: string;
};
handleClose();
setTimeout(() => {
const el = document.getElementById(section);
if (el) el.scrollIntoView({ behavior: "smooth", block: "start" });
if (subAction === "activate-tab" && tabId) setActiveApplicationTab(tabId);
if (subAction === "highlight-node" && nodeId) {
setHighlightedMapNode(nodeId);
setTimeout(() => setHighlightedMapNode(null), 5000);
}
}, 400);
addToolOutput({
tool: "navigate_to_section" as any,
toolCallId: toolCall.toolCallId,
output: `Navigated to "${section}" section${tabId ? `, activated tab "${tabId}"` : ""}${nodeId ? `, highlighted node "${nodeId}"` : ""}`,
});
if (url) {
// Mode B: Cross-page navigation
setTimeout(() => {
router.push(`/${locale}${url}`);
}, 400);
addToolOutput({
tool: "navigate_to_section" as any,
toolCallId: toolCall.toolCallId,
output: `Navigated to page "${url}"`,
});
} else if (section) {
// Mode A: Same-page scroll (existing behavior)
setTimeout(() => {
const el = document.getElementById(section);
if (el) el.scrollIntoView({ behavior: "smooth", block: "start" });
if (subAction === "activate-tab" && tabId) setActiveApplicationTab(tabId);
if (subAction === "highlight-node" && nodeId) {
setHighlightedMapNode(nodeId);
setTimeout(() => setHighlightedMapNode(null), 5000);
}
}, 400);
addToolOutput({
tool: "navigate_to_section" as any,
toolCallId: toolCall.toolCallId,
output: `Navigated to "${section}" section${tabId ? `, activated tab "${tabId}"` : ""}${nodeId ? `, highlighted node "${nodeId}"` : ""}`,
});
}
}
},
});