diff --git a/packages/gitbook/src/components/Adaptive/AIPageNextRecommendedPages.tsx b/packages/gitbook/src/components/Adaptive/AIPageNextRecommendedPages.tsx
deleted file mode 100644
index f7820a5b7..000000000
--- a/packages/gitbook/src/components/Adaptive/AIPageNextRecommendedPages.tsx
+++ /dev/null
@@ -1,60 +0,0 @@
-'use client';
-
-import { tcls } from '@/lib/tailwind';
-import { Icon } from '@gitbook/icons';
-import { useEffect, useState } from 'react';
-import { Link } from '../primitives';
-import { streamNextRecommendedPages } from './server-actions';
-
-/**
- * Show a list of recommended pages to read next.
- */
-export function AIPageNextRecommendedPages(props: {
- spaceId: string;
- revisionId: string;
- pageId: string;
-}) {
- const { spaceId, revisionId, pageId } = props;
-
- const [pages, setPages] = useState<{ title: string; href: string; icon?: string }[]>([]);
-
- useEffect(() => {
- let canceled = false;
-
- setPages([]);
-
- (async () => {
- const stream = await streamNextRecommendedPages({
- spaceId,
- revisionId,
- pageId,
- previousPageIds: [],
- });
-
- for await (const page of stream) {
- if (canceled) {
- return;
- }
-
- setPages((pages) => [...pages, page]);
- }
- })();
-
- return () => {
- canceled = true;
- };
- }, [spaceId, revisionId, pageId]);
-
- return (
-
- {pages.map((page) => {
- return (
-
-
- {page.title}
-
- );
- })}
-
- );
-}
diff --git a/packages/gitbook/src/components/Adaptive/AIPageRecommendedQuestions.tsx b/packages/gitbook/src/components/Adaptive/AIPageRecommendedQuestions.tsx
deleted file mode 100644
index 834407516..000000000
--- a/packages/gitbook/src/components/Adaptive/AIPageRecommendedQuestions.tsx
+++ /dev/null
@@ -1,63 +0,0 @@
-'use client';
-
-import { tcls } from '@/lib/tailwind';
-import { useEffect, useState } from 'react';
-import { Link } from '../primitives';
-import { streamPageRecommendedQuestions } from './server-actions';
-
-/**
- * Show a list of recommended questions for a page.
- */
-export function AIPageRecommendedQuestions(props: {
- spaceId: string;
- revisionId: string;
- pageId: string;
-}) {
- const { spaceId, revisionId, pageId } = props;
-
- const [questions, setQuestions] = useState([]);
-
- useEffect(() => {
- let canceled = false;
-
- setQuestions([]);
-
- (async () => {
- const stream = await streamPageRecommendedQuestions({ spaceId, revisionId, pageId });
- for await (const question of stream) {
- if (canceled) {
- return;
- }
-
- setQuestions((questions) => [...questions, question]);
- }
- })();
-
- return () => {
- canceled = true;
- };
- }, [spaceId, revisionId, pageId]);
-
- return (
-
- {questions.map((question) => {
- const urlParams = new URLSearchParams();
- urlParams.set('q', question);
- urlParams.set('ask', 'true');
-
- return (
-
- {question}
-
- );
- })}
-
- );
-}
diff --git a/packages/gitbook/src/components/Adaptive/AIPageTopics.tsx b/packages/gitbook/src/components/Adaptive/AIPageTopics.tsx
deleted file mode 100644
index 8e72dfa3f..000000000
--- a/packages/gitbook/src/components/Adaptive/AIPageTopics.tsx
+++ /dev/null
@@ -1,65 +0,0 @@
-'use client';
-
-import { tcls } from '@/lib/tailwind';
-import { Icon, type IconName } from '@gitbook/icons';
-import { useEffect, useState } from 'react';
-import { streamPageTopics } from './server-actions/streamPageTopics';
-
-/**
- * Show a list of recommended pages to read next.
- */
-export function AIPageTopics(props: {
- spaceId: string;
- revisionId: string;
- pageId: string;
-}) {
- const { spaceId, revisionId, pageId } = props;
-
- const [topics, setTopics] = useState<{ name?: string; icon?: string }[]>([]);
-
- useEffect(() => {
- let canceled = false;
-
- setTopics([]);
-
- (async () => {
- const stream = await streamPageTopics({
- spaceId,
- revisionId,
- pageId,
- previousPageIds: [],
- });
-
- for await (const topics of stream) {
- if (canceled) {
- return;
- }
-
- setTopics(topics);
- }
- })();
-
- return () => {
- canceled = true;
- };
- }, [spaceId, revisionId, pageId]);
-
- return (
-
- {topics.map((topic) => (
-
- {topic.icon ? (
-
- ) : null}{' '}
- {topic.name}
-
- ))}
-
- );
-}
diff --git a/packages/gitbook/src/components/Adaptive/AdaptivePane.tsx b/packages/gitbook/src/components/Adaptive/AdaptivePane.tsx
deleted file mode 100644
index 7e6bcdbdd..000000000
--- a/packages/gitbook/src/components/Adaptive/AdaptivePane.tsx
+++ /dev/null
@@ -1,82 +0,0 @@
-'use client';
-import React from 'react';
-
-import { useLanguage } from '@/intl/client';
-import { tString } from '@/intl/translate';
-import { tcls } from '@/lib/tailwind';
-import { Button } from '../primitives';
-import { AIPageNextRecommendedPages } from './AIPageNextRecommendedPages';
-import { AIPageTopics } from './AIPageTopics';
-import { useAdaptivePane } from './state';
-
-export function AdaptivePane(props: { spaceId: string; revisionId: string; pageId: string }) {
- const language = useLanguage();
- const { opened, open, close } = useAdaptivePane();
-
- const { spaceId, revisionId, pageId } = props;
-
- React.useEffect(() => {
- if (opened) {
- document.body.classList.add('adaptive-pane');
- } else {
- document.body.classList.remove('adaptive-pane');
- }
- }, [opened]);
-
- const pages = [
- 'GitBook Documentation',
- 'GitHub & GitLab Sync',
- 'Troubleshooting',
- 'Version control',
- ];
-
- return (
-
-
-
-
-
- Recommended
-
-
Based on your context
-
-
-
-
-
- );
-}
diff --git a/packages/gitbook/src/components/Adaptive/index.ts b/packages/gitbook/src/components/Adaptive/index.ts
index 49381610c..2d93029d7 100644
--- a/packages/gitbook/src/components/Adaptive/index.ts
+++ b/packages/gitbook/src/components/Adaptive/index.ts
@@ -1,3 +1 @@
-export * from './AIPageRecommendedQuestions';
-export * from './AIPageNextRecommendedPages';
-export * from './AdaptivePane';
+export * from './AIPageLinkSummary';
diff --git a/packages/gitbook/src/components/Adaptive/server-actions/api.ts b/packages/gitbook/src/components/Adaptive/server-actions/api.ts
index 938f5915a..401a2ec47 100644
--- a/packages/gitbook/src/components/Adaptive/server-actions/api.ts
+++ b/packages/gitbook/src/components/Adaptive/server-actions/api.ts
@@ -60,7 +60,6 @@ export async function streamGenerateObject(
input: messages,
output: {
type: 'object',
- // @ts-expect-error
schema: zodToJsonSchema(schema),
},
model,
diff --git a/packages/gitbook/src/components/Adaptive/server-actions/streamNextRecommendedPages.ts b/packages/gitbook/src/components/Adaptive/server-actions/streamNextRecommendedPages.ts
deleted file mode 100644
index 7743ac7a6..000000000
--- a/packages/gitbook/src/components/Adaptive/server-actions/streamNextRecommendedPages.ts
+++ /dev/null
@@ -1,116 +0,0 @@
-'use server';
-
-import { resolvePageId } from '@/lib/pages';
-import { getV1BaseContext } from '@/lib/v1';
-import { isV2 } from '@/lib/v2';
-import { AIMessageRole } from '@gitbook/api';
-import { getSiteURLDataFromMiddleware } from '@v2/lib/middleware';
-import { fetchServerActionSiteContext, getServerActionBaseContext } from '@v2/lib/server-actions';
-import { z } from 'zod';
-import { streamGenerateObject } from './api';
-
-/**
- * Get a list of pages that are recommended to be read next.
- */
-export async function* streamNextRecommendedPages({
- spaceId,
- revisionId,
- previousPageIds,
- pageId,
-}: {
- spaceId: string;
- revisionId: string;
- previousPageIds: string[];
- pageId: string;
-}) {
- const baseContext = isV2() ? await getServerActionBaseContext() : await getV1BaseContext();
- const siteURLData = await getSiteURLDataFromMiddleware();
-
- const [{ stream }, context] = await Promise.all([
- streamGenerateObject(
- baseContext,
- {
- organizationId: siteURLData.organization,
- siteId: siteURLData.site,
- },
- {
- schema: z.object({
- pages: z.array(z.string().describe('The id of the page')).max(5),
- }),
- messages: [
- {
- role: AIMessageRole.Developer,
- content:
- 'You are an AI to help users navigate and get the most out of the documentation. Using the table of contents and a list of pages that the user has visited, generate a list of pages that are relevant to read next.',
- },
- {
- role: AIMessageRole.User,
- content: 'Pages in the documentation:',
- attachments: [
- {
- type: 'pages',
- spaceId,
- revisionId,
- },
- ],
- },
- ...(previousPageIds.length > 0
- ? [
- {
- role: AIMessageRole.User,
- content: `The user has visited the following pages: ${previousPageIds.join(', ')}`,
- },
- ]
- : []),
- {
- role: AIMessageRole.User,
- content: `The user is currently on the page "${pageId}", the content of the page is:`,
- attachments: [
- {
- type: 'page',
- spaceId,
- revisionId,
- pageId,
- },
- ],
- },
- ],
- }
- ),
- fetchServerActionSiteContext(baseContext),
- ]);
-
- const emitted = new Set();
- for await (const value of stream) {
- const pages = value.pages;
- if (!pages) {
- continue;
- }
-
- for (const pageId of pages) {
- if (!pageId) {
- continue;
- }
-
- if (emitted.has(pageId)) {
- continue;
- }
-
- emitted.add(pageId);
-
- const page = resolvePageId(context.pages, pageId);
- if (!page) {
- continue;
- }
-
- yield {
- icon: page.page.icon ?? page.page.emoji,
- title: page.page.title,
- href: context.linker.toPathForPage({
- pages: context.pages,
- page: page.page,
- }),
- };
- }
- }
-}
diff --git a/packages/gitbook/src/components/Adaptive/server-actions/streamPageRecommendedQuestions.ts b/packages/gitbook/src/components/Adaptive/server-actions/streamPageRecommendedQuestions.ts
deleted file mode 100644
index f71c01f31..000000000
--- a/packages/gitbook/src/components/Adaptive/server-actions/streamPageRecommendedQuestions.ts
+++ /dev/null
@@ -1,89 +0,0 @@
-'use server';
-
-import { getV1BaseContext } from '@/lib/v1';
-import { isV2 } from '@/lib/v2';
-import { AIMessageRole } from '@gitbook/api';
-import { getSiteURLDataFromMiddleware } from '@v2/lib/middleware';
-import { getServerActionBaseContext } from '@v2/lib/server-actions';
-import { z } from 'zod';
-import { streamGenerateObject } from './api';
-
-/**
- * Get a list of questions that are recommended to be asked on a page.
- */
-export async function* streamPageRecommendedQuestions({
- spaceId,
- revisionId,
- pageId,
-}: {
- spaceId: string;
- revisionId: string;
- pageId: string;
-}) {
- const baseContext = isV2() ? await getServerActionBaseContext() : await getV1BaseContext();
- const siteURLData = await getSiteURLDataFromMiddleware();
-
- const { stream } = await streamGenerateObject(
- baseContext,
- {
- organizationId: siteURLData.organization,
- siteId: siteURLData.site,
- },
- {
- schema: z.object({
- questions: z.array(z.string()).max(5),
- }),
- messages: [
- {
- role: AIMessageRole.Developer,
- content:
- 'You are an AI to help users navigate and get the most out of the documentation. Based on the content of the page, generate a list of questions that are relevant to ask after reading the page.',
- },
- {
- role: AIMessageRole.User,
- content: 'Pages in the documentation:',
- attachments: [
- {
- type: 'pages',
- spaceId,
- revisionId,
- },
- ],
- },
- {
- role: AIMessageRole.User,
- content: 'Content of the current page:',
- attachments: [
- {
- type: 'page',
- spaceId,
- revisionId,
- pageId,
- },
- ],
- },
- ],
- }
- );
-
- const emitted = new Set();
- for await (const value of stream) {
- const questions = value.questions;
- if (!questions) {
- continue;
- }
-
- for (const question of questions) {
- if (!question) {
- continue;
- }
-
- if (emitted.has(question)) {
- continue;
- }
-
- emitted.add(question);
- yield question;
- }
- }
-}
diff --git a/packages/gitbook/src/components/Adaptive/server-actions/streamPageTopics.ts b/packages/gitbook/src/components/Adaptive/server-actions/streamPageTopics.ts
deleted file mode 100644
index d8802e8a3..000000000
--- a/packages/gitbook/src/components/Adaptive/server-actions/streamPageTopics.ts
+++ /dev/null
@@ -1,120 +0,0 @@
-'use server';
-import { getV1BaseContext } from '@/lib/v1';
-import { isV2 } from '@/lib/v2';
-import { AIMessageRole } from '@gitbook/api';
-import { getSiteURLDataFromMiddleware } from '@v2/lib/middleware';
-import { fetchServerActionSiteContext, getServerActionBaseContext } from '@v2/lib/server-actions';
-import { z } from 'zod';
-import { streamGenerateObject } from './api';
-
-/**
- * Get a list of pages that are recommended to be read next.
- */
-export async function* streamPageTopics({
- spaceId,
- revisionId,
- previousPageIds,
- pageId,
-}: {
- spaceId: string;
- revisionId: string;
- previousPageIds: string[];
- pageId: string;
-}) {
- const baseContext = isV2() ? await getServerActionBaseContext() : await getV1BaseContext();
- const siteURLData = await getSiteURLDataFromMiddleware();
-
- const [{ stream }, context] = await Promise.all([
- streamGenerateObject(
- baseContext,
- {
- organizationId: siteURLData.organization,
- siteId: siteURLData.site,
- },
- {
- schema: z.object({
- topics: z
- .array(
- z.object({
- name: z.string().describe('The recommended topic name'),
- icon: z
- .string()
- .describe(
- 'A fontawesome icon name to describe the topic, without the `fa-` part.'
- ),
- })
- )
- .max(4),
- }),
- messages: [
- {
- role: AIMessageRole.Developer,
- content: `
-# Task
-You are a documentation navigator, tasked with helping the user navigate through documentation.
-The user is currently reading a page, and is considering next pages to navigate to.
-Gather topics present in the documentation, and present the relevant topics to the user given their existing page and context. These topics will inform next pages to visit.
-Topics always contain a verb and a subject. Use sentence case (capitalise first word only).
-`,
- },
- {
- role: AIMessageRole.User,
- content: 'Pages in the documentation:',
- attachments: [
- {
- type: 'pages',
- spaceId,
- },
- ],
- },
- ...(previousPageIds.length > 0
- ? [
- {
- role: AIMessageRole.User,
- content: `The user has visited the following pages: ${previousPageIds.join(', ')}`,
- },
- ]
- : []),
- {
- role: AIMessageRole.User,
- content: `The user is currently on the page "${pageId}", the content of the page is:`,
- attachments: [
- {
- type: 'page',
- spaceId,
- pageId,
- },
- ],
- },
- ],
- }
- ),
- fetchServerActionSiteContext(baseContext),
- ]);
-
- // const emitted = new Set<{ id: string, name?: string; icon?: string }>();
- for await (const value of stream) {
- const topics = value.topics;
- if (!topics) {
- continue;
- }
-
- // for (const topic of topics) {
- // if (!topic) {
- // continue;
- // }
-
- // // const page = resolvePageId(context.pages, pageId);
- // if (!topic.name || !topic.icon) {
- // continue;
- // }
-
- // emitted.has(topic)
- // yield {
- // name: topic.name,
- // icon: topic.icon,
- // };
- // }
- yield topics;
- }
-}
diff --git a/packages/gitbook/src/components/Adaptive/state.ts b/packages/gitbook/src/components/Adaptive/state.ts
deleted file mode 100644
index fdef63db0..000000000
--- a/packages/gitbook/src/components/Adaptive/state.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-import { create } from 'zustand';
-
-export const useAdaptivePane = create<{
- opened: boolean;
- open: () => void;
- close: () => void;
-}>((set) => ({
- opened: true,
-
- /**
- * Open the adaptive pane
- */
- open: () => set({ opened: true }),
-
- /**
- * Close the adaptive pane
- */
- close: () => set({ opened: false }),
-}));
diff --git a/packages/gitbook/src/components/PageAside/PageAside.tsx b/packages/gitbook/src/components/PageAside/PageAside.tsx
index 81df45120..af87af99e 100644
--- a/packages/gitbook/src/components/PageAside/PageAside.tsx
+++ b/packages/gitbook/src/components/PageAside/PageAside.tsx
@@ -13,7 +13,6 @@ import urlJoin from 'url-join';
import { getSpaceLanguage, t } from '@/intl/server';
import { getDocumentSections } from '@/lib/document-sections';
import { tcls } from '@/lib/tailwind';
-import { AIPageNextRecommendedPages } from '../Adaptive';
import { Ad } from '../Ads';
import { getPDFURLSearchParams } from '../PDF';
import { PageFeedbackForm } from '../PageFeedback';
@@ -43,8 +42,6 @@ export function PageAside(props: {
}).toString()}`
);
- const prevPages = ['GitBook Documentation', 'GitHub & GitLab Sync', 'Troubleshooting'];
-
return (