-
Notifications
You must be signed in to change notification settings - Fork 354
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
35 changed files
with
1,643 additions
and
472 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,117 @@ | ||
import { PipelinesService } from "@llamaindex/cloud/api"; | ||
import { rehypeCodeDefaultOptions } from "fumadocs-core/mdx-plugins"; | ||
import { fileGenerator, remarkDocGen, remarkInstall } from "fumadocs-docgen"; | ||
import { defineConfig, defineDocs } from "fumadocs-mdx/config"; | ||
import { transformerTwoslash } from "fumadocs-twoslash"; | ||
import { relative } from "node:path"; | ||
import { fileURLToPath } from "node:url"; | ||
import rehypeKatex from "rehype-katex"; | ||
import remarkMath from "remark-math"; | ||
|
||
const baseDir = fileURLToPath(new URL("../src/content", import.meta.url)); | ||
|
||
export const { docs, meta } = defineDocs({ | ||
dir: "./src/content/docs", | ||
}); | ||
|
||
export default defineConfig(); | ||
export default defineConfig({ | ||
lastModifiedTime: "git", | ||
mdxOptions: { | ||
rehypeCodeOptions: { | ||
inline: "tailing-curly-colon", | ||
themes: { | ||
light: "catppuccin-latte", | ||
dark: "catppuccin-mocha", | ||
}, | ||
transformers: [ | ||
...(rehypeCodeDefaultOptions.transformers ?? []), | ||
transformerTwoslash(), | ||
{ | ||
name: "transformers:remove-notation-escape", | ||
code(hast) { | ||
for (const line of hast.children) { | ||
if (line.type !== "element") continue; | ||
|
||
const lastSpan = line.children.findLast( | ||
(v) => v.type === "element", | ||
); | ||
|
||
const head = lastSpan?.children[0]; | ||
if (head?.type !== "text") return; | ||
|
||
head.value = head.value.replace(/\[\\!code/g, "[!code"); | ||
} | ||
}, | ||
}, | ||
], | ||
}, | ||
remarkPlugins: [ | ||
remarkMath, | ||
[remarkInstall, { persist: { id: "package-manager" } }], | ||
[remarkDocGen, { generators: [fileGenerator()] }], | ||
() => { | ||
return (_, file, next) => { | ||
const metadata = file.data.frontmatter as Record<string, unknown>; | ||
const title = metadata.title as string; | ||
const description = metadata.description as string; | ||
let content: string; | ||
if (file.value instanceof Uint8Array) { | ||
content = file.value.toString(); | ||
} else { | ||
content = file.value; | ||
} | ||
if (file.path.includes("content/docs/cloud/api")) { | ||
// skip cloud api docs | ||
return next(); | ||
} | ||
// eslint-disable-next-line turbo/no-undeclared-env-vars | ||
if (process.env.NODE_ENV === "development") { | ||
// skip development | ||
return next(); | ||
} | ||
if (!title || !description) { | ||
throw new Error(`Missing title or description in ${file.path}`); | ||
} | ||
const id = relative(baseDir, file.path); | ||
|
||
if ( | ||
// eslint-disable-next-line turbo/no-undeclared-env-vars | ||
process.env.LLAMA_CLOUD_UPSERT_PIPELINE_DOCUMENTS === "true" && | ||
// eslint-disable-next-line turbo/no-undeclared-env-vars | ||
process.env.LLAMA_CLOUD_PIPELINE_ID !== undefined | ||
) { | ||
PipelinesService.upsertBatchPipelineDocumentsApiV1PipelinesPipelineIdDocumentsPut( | ||
{ | ||
baseUrl: "https://api.cloud.llamaindex.ai/", | ||
body: [ | ||
{ | ||
metadata: { | ||
title, | ||
description, | ||
documentUrl: id, | ||
}, | ||
text: content, | ||
id, | ||
}, | ||
], | ||
path: { | ||
// eslint-disable-next-line turbo/no-undeclared-env-vars | ||
pipeline_id: process.env.LLAMA_CLOUD_PIPELINE_ID, | ||
}, | ||
throwOnError: true, | ||
headers: { | ||
// eslint-disable-next-line turbo/no-undeclared-env-vars | ||
Authorization: `Bearer ${process.env.LLAMA_CLOUD_API_KEY}`, | ||
}, | ||
}, | ||
).catch((error) => { | ||
console.error(error); | ||
}); | ||
} | ||
return next(); | ||
}; | ||
}, | ||
], | ||
rehypePlugins: (v) => [rehypeKatex, ...v], | ||
}, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
import { ClientMDXContent } from "@/components/mdx"; | ||
import { BotMessage } from "@/components/message"; | ||
import { Skeleton } from "@/components/ui/skeleton"; | ||
import { LlamaCloudRetriever } from "@/deps/cloud"; | ||
import { Settings } from "@llamaindex/core/global"; | ||
import { ChatMessage } from "@llamaindex/core/llms"; | ||
import { RetrieverQueryEngine } from "@llamaindex/core/query-engine"; | ||
import { OpenAI } from "@llamaindex/openai"; | ||
import { createAI, createStreamableUI, getMutableAIState } from "ai/rsc"; | ||
import { ReactNode } from "react"; | ||
|
||
Settings.llm = new OpenAI({ | ||
model: "gpt-4o", | ||
}); | ||
|
||
const retriever = new LlamaCloudRetriever({ | ||
// eslint-disable-next-line turbo/no-undeclared-env-vars | ||
apiKey: process.env.LLAMA_CLOUD_API_KEY!, | ||
baseUrl: "https://api.cloud.llamaindex.ai/", | ||
// eslint-disable-next-line turbo/no-undeclared-env-vars | ||
pipelineId: process.env.LLAMA_CLOUD_PIPELINE_ID!, | ||
}); | ||
|
||
const initialAIState = { | ||
messages: [], | ||
} as { | ||
messages: ChatMessage[]; | ||
}; | ||
|
||
type UIMessage = { | ||
id: number; | ||
display: ReactNode; | ||
}; | ||
|
||
const initialUIState = { | ||
messages: [], | ||
} as { | ||
messages: UIMessage[]; | ||
}; | ||
|
||
const runAsyncFnWithoutBlocking = (fn: (...args: any) => Promise<any>) => { | ||
fn().catch((error) => { | ||
console.error(error); | ||
}); | ||
}; | ||
|
||
export const AIProvider = createAI({ | ||
initialAIState, | ||
initialUIState, | ||
actions: { | ||
query: async (message: string): Promise<UIMessage> => { | ||
"use server"; | ||
const queryEngine = new RetrieverQueryEngine(retriever); | ||
|
||
const id = Date.now(); | ||
const aiState = getMutableAIState<typeof AIProvider>(); | ||
aiState.update({ | ||
...aiState.get(), | ||
messages: [ | ||
...aiState.get().messages, | ||
{ | ||
role: "user", | ||
content: message, | ||
}, | ||
], | ||
}); | ||
|
||
const ui = createStreamableUI( | ||
<div className="space-y-2"> | ||
<Skeleton className="h-4 w-full" /> | ||
<Skeleton className="h-4 w-full" /> | ||
</div>, | ||
); | ||
|
||
runAsyncFnWithoutBlocking(async () => { | ||
const response = await queryEngine.query({ | ||
query: message, | ||
stream: true, | ||
}); | ||
let content = ""; | ||
|
||
for await (const { delta } of response) { | ||
content += delta; | ||
ui.update(<ClientMDXContent id={id} content={content} />); | ||
} | ||
|
||
ui.done(); | ||
|
||
aiState.done({ | ||
...aiState.get(), | ||
messages: [ | ||
...aiState.get().messages, | ||
{ | ||
role: "assistant", | ||
content, | ||
}, | ||
], | ||
}); | ||
}); | ||
|
||
return { | ||
id, | ||
display: <BotMessage>{ui.value}</BotMessage>, | ||
}; | ||
}, | ||
}, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.