Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
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
104 changes: 52 additions & 52 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,34 +30,34 @@
"packageManager": "pnpm@10.14.0",
"dependencies": {
"@ai-sdk/devtools": "^0.0.15",
"@ai-sdk/google": "^3.0.55",
"@assistant-ui/react": "^0.12.21",
"@assistant-ui/react-ai-sdk": "^1.3.16",
"@assistant-ui/react-devtools": "^1.0.2",
"@assistant-ui/react-markdown": "^0.12.7",
"@embedpdf/core": "^2.10.1",
"@embedpdf/engines": "^2.10.1",
"@embedpdf/models": "^2.10.1",
"@embedpdf/plugin-annotation": "^2.10.1",
"@embedpdf/plugin-capture": "^2.10.1",
"@embedpdf/plugin-document-manager": "^2.10.1",
"@embedpdf/plugin-export": "^2.10.1",
"@embedpdf/plugin-fullscreen": "^2.10.1",
"@embedpdf/plugin-history": "^2.10.1",
"@embedpdf/plugin-interaction-manager": "^2.10.1",
"@embedpdf/plugin-pan": "^2.10.1",
"@embedpdf/plugin-render": "^2.10.1",
"@embedpdf/plugin-rotate": "^2.10.1",
"@embedpdf/plugin-scroll": "^2.10.1",
"@embedpdf/plugin-search": "^2.10.1",
"@embedpdf/plugin-selection": "^2.10.1",
"@embedpdf/plugin-thumbnail": "^2.10.1",
"@embedpdf/plugin-tiling": "^2.10.1",
"@embedpdf/plugin-viewport": "^2.10.1",
"@embedpdf/plugin-zoom": "^2.10.1",
"@ai-sdk/google": "^3.0.58",
"@assistant-ui/react": "^0.12.23",
"@assistant-ui/react-ai-sdk": "^1.3.17",
"@assistant-ui/react-devtools": "^1.0.4",
"@assistant-ui/react-markdown": "^0.12.8",
"@embedpdf/core": "^2.14.0",
"@embedpdf/engines": "^2.14.0",
"@embedpdf/models": "^2.14.0",
"@embedpdf/plugin-annotation": "^2.14.0",
"@embedpdf/plugin-capture": "^2.14.0",
"@embedpdf/plugin-document-manager": "^2.14.0",
"@embedpdf/plugin-export": "^2.14.0",
"@embedpdf/plugin-fullscreen": "^2.14.0",
"@embedpdf/plugin-history": "^2.14.0",
"@embedpdf/plugin-interaction-manager": "^2.14.0",
"@embedpdf/plugin-pan": "^2.14.0",
"@embedpdf/plugin-render": "^2.14.0",
"@embedpdf/plugin-rotate": "^2.14.0",
"@embedpdf/plugin-scroll": "^2.14.0",
"@embedpdf/plugin-search": "^2.14.0",
"@embedpdf/plugin-selection": "^2.14.0",
"@embedpdf/plugin-thumbnail": "^2.14.0",
"@embedpdf/plugin-tiling": "^2.14.0",
"@embedpdf/plugin-viewport": "^2.14.0",
"@embedpdf/plugin-zoom": "^2.14.0",
"@floating-ui/react": "^0.27.19",
"@google/genai": "^1.42.0",
"@lottiefiles/dotlottie-react": "^0.18.7",
"@google/genai": "^1.48.0",
"@lottiefiles/dotlottie-react": "^0.18.9",
"@opentelemetry/api": "^1.9.1",
"@opentelemetry/api-logs": "^0.214.0",
"@opentelemetry/exporter-trace-otlp-http": "^0.214.0",
Expand Down Expand Up @@ -86,26 +86,26 @@
"@supabase/supabase-js": "^2.101.1",
"@tanstack/react-query": "^5.96.1",
"@tanstack/react-query-devtools": "^5.96.1",
"@tiptap/core": "3.22.1",
"@tiptap/extension-code-block": "3.22.1",
"@tiptap/extension-highlight": "3.22.1",
"@tiptap/extension-horizontal-rule": "3.22.1",
"@tiptap/extension-image": "3.22.1",
"@tiptap/extension-list": "3.22.1",
"@tiptap/extension-mathematics": "3.22.1",
"@tiptap/extension-subscript": "3.22.1",
"@tiptap/extension-superscript": "3.22.1",
"@tiptap/extension-table": "3.22.1",
"@tiptap/extension-text-align": "3.22.1",
"@tiptap/extension-typography": "3.22.1",
"@tiptap/extensions": "3.22.1",
"@tiptap/markdown": "3.22.1",
"@tiptap/pm": "3.22.1",
"@tiptap/react": "3.22.1",
"@tiptap/starter-kit": "3.22.1",
"@tiptap/core": "3.22.2",
"@tiptap/extension-code-block": "3.22.2",
"@tiptap/extension-highlight": "3.22.2",
"@tiptap/extension-horizontal-rule": "3.22.2",
"@tiptap/extension-image": "3.22.2",
"@tiptap/extension-list": "3.22.2",
"@tiptap/extension-mathematics": "3.22.2",
"@tiptap/extension-subscript": "3.22.2",
"@tiptap/extension-superscript": "3.22.2",
"@tiptap/extension-table": "3.22.2",
"@tiptap/extension-text-align": "3.22.2",
"@tiptap/extension-typography": "3.22.2",
"@tiptap/extensions": "3.22.2",
"@tiptap/markdown": "3.22.2",
"@tiptap/pm": "3.22.2",
"@tiptap/react": "3.22.2",
"@tiptap/starter-kit": "3.22.2",
"@vercel/otel": "^2.1.1",
"ai": "^6.0.143",
"assistant-stream": "^0.3.8",
"ai": "^6.0.146",
"assistant-stream": "^0.3.10",
"better-auth": "^1.5.6",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
Expand All @@ -116,15 +116,15 @@
"gsap": "^3.14.2",
"heic2any": "^0.0.4",
"jsonrepair": "^3.13.2",
"katex": "^0.16.44",
"katex": "^0.16.45",
"lodash.throttle": "^4.1.1",
"lucide-react": "^1.7.0",
"next": "16.2.2",
"next-themes": "^0.4.6",
"parse-diff": "^0.11.1",
"postcss": "^8.5.8",
"postgres": "^3.4.7",
"posthog-js": "^1.364.6",
"postgres": "^3.4.9",
"posthog-js": "^1.364.7",
"posthog-node": "^5.28.11",
"prosemirror-highlight": "^0.15.1",
"radix-ui": "^1.4.3",
Expand All @@ -137,22 +137,22 @@
"react-icons": "^5.5.0",
"react-markdown": "^10.1.0",
"react-quizlet-flashcard": "^4.0.22",
"react-resizable-panels": "^4.7.5",
"react-resizable-panels": "^4.9.0",
"react-shiki": "^0.9.1",
"react-speech-recognition": "^4.0.1",
"regenerator-runtime": "^0.14.1",
"rehype-katex": "^7.0.1",
"remark-gfm": "^4.0.1",
"remark-math": "^6.0.0",
"resend": "^6.9.2",
"resend": "^6.10.0",
"server-only": "^0.0.1",
"shiki": "^4.0.2",
"sonner": "^2.0.7",
"streamdown": "^2.4.0",
"tailwind-merge": "^3.5.0",
"tw-shimmer": "^0.4.9",
"unicodeit": "^0.7.5",
"workflow": "4.2.0-beta.75",
"workflow": "4.2.0-beta.76",
"zod": "^4.3.6",
"zustand": "^5.0.11"
},
Expand Down
52 changes: 8 additions & 44 deletions src/app/api/chat/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,40 +36,6 @@ function extractWorkspaceId(body: any): string | null {
return null;
}

/**
* Process messages in a single pass: clean URL context markers
* File attachments are handled natively as file parts via the SupabaseAttachmentAdapter.
*/
function processMessages(messages: any[]): {
cleanedMessages: any[];
} {
const cleanedMessages = messages.map((message) => {
if (message.content && Array.isArray(message.content)) {
const updatedContent = message.content.map((part: any) => {
if (part.type === "text" && typeof part.text === "string") {
const text = part.text;

const updatedText = text.replace(
/\[URL_CONTEXT:(.+?)\]/g,
(_match: string, url: string) => {
return url;
},
);

return { ...part, text: updatedText };
}
return part;
});
return { ...message, content: updatedContent } as typeof message;
}
return message;
});

return {
cleanedMessages,
};
}

/**
* Selected cards context is now formatted on the client side and sent directly.
* This eliminates the need for server-side database fetch.
Expand Down Expand Up @@ -167,10 +133,11 @@ async function handlePOST(req: Request) {
activeFolderId,
threadId,
clientTools: body.tools,
enableMagicFetch: true, // experiment: log AI data requests to PostHog
});

const compatibleMessages = normalizeLegacyToolMessages(messages);
const compatibleMessages = normalizeLegacyToolMessages(messages, {
availableToolNames: Object.keys(tools),
});

const validation = await safeValidateUIMessages({
messages: compatibleMessages,
Expand Down Expand Up @@ -206,9 +173,6 @@ async function handlePOST(req: Request) {
emptyMessages: "remove",
});

// Process messages in single pass: clean URL context markers
const { cleanedMessages } = processMessages(convertedMessages);

// Get pre-formatted selected cards context from client (no DB fetch needed)
const selectedCardsContext = getSelectedCardsContext(body);

Expand All @@ -228,7 +192,7 @@ async function handlePOST(req: Request) {

// Inject selected cards + reply selections into the last user message
injectSelectionContext(
cleanedMessages,
convertedMessages,
body.metadata?.custom,
selectedCardsContext,
);
Expand All @@ -253,15 +217,15 @@ async function handlePOST(req: Request) {
});

// Stream the response
logger.debug("🔍 [CHAT-API] Final cleanedMessages before streamText:", {
count: cleanedMessages.length,
logger.debug("🔍 [CHAT-API] Final messages before streamText:", {
count: convertedMessages.length,
modelId,
});

// Configure Google Thinking capabilities
const googleConfig: any = {
grounding: {
// googleSearchRetrieval removed to force usage of explicit webSearch tool
// googleSearchRetrieval removed to force usage of explicit web_search tool
},
thinkingConfig: {
includeThoughts: true,
Expand Down Expand Up @@ -297,7 +261,7 @@ async function handlePOST(req: Request) {
model: model,
temperature: 1.0,
system,
messages: cleanedMessages,
messages: convertedMessages,
stopWhen: stepCountIs(25),
tools,
providerOptions,
Expand Down
8 changes: 4 additions & 4 deletions src/app/api/workspaces/autogen/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,9 +148,9 @@ If needsSearch=true, provide a searchQuery (2-6 words) to look up.`,
}

const query = String(output.searchQuery).trim();
send({ type: "toolCall", data: { toolName: "webSearch", query, status: "searching" } });
send({ type: "toolCall", data: { toolName: "web_search", query, status: "searching" } });
const { text, sources } = await executeWebSearch(query);
send({ type: "toolResult", data: { toolName: "webSearch", status: "done" } });
send({ type: "toolResult", data: { toolName: "web_search", status: "done" } });

const searchContext = `\n\nCONTEXT FROM WEB SEARCH (use this to inform your response):\n${text}`;
return { searchContext, sources };
Expand All @@ -172,7 +172,7 @@ async function runDistillationAgent(
const nonYtLinks = links?.filter((l) => !isYouTubeUrl(l)) ?? [];
let linkContext = "";
if (nonYtLinks.length > 0) {
send({ type: "toolCall", data: { toolName: "urlFetch", status: "fetching" } });
send({ type: "toolCall", data: { toolName: "web_fetch", status: "fetching" } });
Comment thread
coderabbitai[bot] marked this conversation as resolved.
const client = new FirecrawlClient();
const results = await client.scrapeUrls(nonYtLinks);
const successful = results.filter((r) => r.success && r.content);
Expand All @@ -186,7 +186,7 @@ async function runDistillationAgent(
})
.join("\n\n---\n\n");
}
send({ type: "toolResult", data: { toolName: "urlFetch", status: "done" } });
send({ type: "toolResult", data: { toolName: "web_fetch", status: "done" } });
}

const userMessage = buildUserMessage(prompt, fileUrls, links);
Expand Down
5 changes: 3 additions & 2 deletions src/app/generate/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { WorkspaceProvider } from "@/contexts/WorkspaceContext";
import { MobileWarning } from "@/components/ui/MobileWarning";
import { FloatingWorkspaceCards } from "@/components/background/FloatingWorkspaceCards";
import { ATTACHMENTS_SESSION_KEY } from "@/contexts/HomeAttachmentsContext";
import { matchesWebSearchStreamToolName } from "@/lib/ai/chat-tool-names";

const PROGRESS_LABELS: Record<string, string> = {
understanding: "Understanding content...",
Expand Down Expand Up @@ -127,12 +128,12 @@ function GenerateContent() {

if (ev.type === "phase" && ev.data?.stage === "understanding") {
applyIfNotAborted(() => setProgressText("Understanding content..."));
} else if (ev.type === "toolCall" && ev.data?.toolName === "webSearch" && ev.data?.query) {
} else if (ev.type === "toolCall" && matchesWebSearchStreamToolName(ev.data?.toolName) && ev.data?.query) {
const q = ev.data.query;
applyIfNotAborted(() =>
setProgressText(`Searching the web for: "${q.length > 50 ? q.slice(0, 50) + "..." : q}"`)
);
} else if (ev.type === "toolResult" && ev.data?.toolName === "webSearch") {
} else if (ev.type === "toolResult" && matchesWebSearchStreamToolName(ev.data?.toolName)) {
applyIfNotAborted(() => setProgressText("Processing search results..."));
} else if (ev.type === "partial" && ev.data?.partial) {
const p = ev.data.partial as Record<string, unknown>;
Expand Down
Loading
Loading