From cc26fb34aab1efc15c7fb55f87c4320db450419f Mon Sep 17 00:00:00 2001 From: Zeno Kapitein Date: Thu, 3 Apr 2025 13:48:35 +0200 Subject: [PATCH] Remove other AI experiments (for now) --- .../Adaptive/AIPageNextRecommendedPages.tsx | 60 --------- .../Adaptive/AIPageRecommendedQuestions.tsx | 63 --------- .../src/components/Adaptive/AIPageTopics.tsx | 65 ---------- .../src/components/Adaptive/AdaptivePane.tsx | 82 ------------ .../gitbook/src/components/Adaptive/index.ts | 4 +- .../components/Adaptive/server-actions/api.ts | 1 - .../streamNextRecommendedPages.ts | 116 ----------------- .../streamPageRecommendedQuestions.ts | 89 ------------- .../server-actions/streamPageTopics.ts | 120 ------------------ .../gitbook/src/components/Adaptive/state.ts | 19 --- .../src/components/PageAside/PageAside.tsx | 20 --- .../src/components/SitePage/SitePage.tsx | 2 - 12 files changed, 1 insertion(+), 640 deletions(-) delete mode 100644 packages/gitbook/src/components/Adaptive/AIPageNextRecommendedPages.tsx delete mode 100644 packages/gitbook/src/components/Adaptive/AIPageRecommendedQuestions.tsx delete mode 100644 packages/gitbook/src/components/Adaptive/AIPageTopics.tsx delete mode 100644 packages/gitbook/src/components/Adaptive/AdaptivePane.tsx delete mode 100644 packages/gitbook/src/components/Adaptive/server-actions/streamNextRecommendedPages.ts delete mode 100644 packages/gitbook/src/components/Adaptive/server-actions/streamPageRecommendedQuestions.ts delete mode 100644 packages/gitbook/src/components/Adaptive/server-actions/streamPageTopics.ts delete mode 100644 packages/gitbook/src/components/Adaptive/state.ts 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 (