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:
@@ -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}"` : ""}`,
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user