diff --git a/docs/docs.trychroma.com/app/[...slug]/layout.tsx b/docs/docs.trychroma.com/app/[...slug]/layout.tsx new file mode 100644 index 00000000000..6e95cde72f1 --- /dev/null +++ b/docs/docs.trychroma.com/app/[...slug]/layout.tsx @@ -0,0 +1,20 @@ +import React from "react"; +import Sidebar from "@/components/sidebar/sidebar"; + +interface LayoutProps { + children: React.ReactNode; + params: { slug: string[] }; +} + +const PageLayout: React.FC = ({ children, params }) => { + const { slug } = params; + + return ( +
+ +
{children}
+
+ ); +}; + +export default PageLayout; diff --git a/docs/docs.trychroma.com/app/[...slug]/not-found.tsx b/docs/docs.trychroma.com/app/[...slug]/not-found.tsx new file mode 100644 index 00000000000..32c601f0168 --- /dev/null +++ b/docs/docs.trychroma.com/app/[...slug]/not-found.tsx @@ -0,0 +1,19 @@ +import React from "react"; +import CodeBlock from "@/components/markdoc/code-block"; + +const notFoundCode = ` +import chromadb + +client = chromadb.Client() +collection = client.get_collection(name="chroma_docs") +results = collection.get(ids=["page"])["documents"] +print(results) # Not found [] +` + +const NotFound = () => { + return
+ +
+} + +export default NotFound; \ No newline at end of file diff --git a/docs/docs.trychroma.com/app/[...slug]/page.tsx b/docs/docs.trychroma.com/app/[...slug]/page.tsx new file mode 100644 index 00000000000..4c59efdd015 --- /dev/null +++ b/docs/docs.trychroma.com/app/[...slug]/page.tsx @@ -0,0 +1,37 @@ +import React from "react"; +import MarkdocRenderer from "@/components/markdoc/markdoc-renderer"; +import sidebarConfig from "@/markdoc/content/sidebar-config"; +import { AppSection } from "@/lib/content"; + +export const generateStaticParams = async () => { + const slugs: string[][] = []; + + const traverseSection = (section: AppSection, path: string[] = []) => { + if (section.pages) { + section.pages.forEach((page) => { + slugs.push([...path, page.id]); + }); + } + + if (section.subsections) { + section.subsections.forEach((subsection) => { + traverseSection(subsection, [...path, subsection.id]); + }); + } + }; + + sidebarConfig.forEach((section) => { + traverseSection(section, [section.id]); + }); + + return slugs.map((slug) => ({ + slug, + })); +}; + +const Page: React.FC<{ params: { slug: string[] } }> = ({ params }) => { + const { slug } = params; + return ; +}; + +export default Page; diff --git a/docs/docs.trychroma.com/app/cloud/page.tsx b/docs/docs.trychroma.com/app/cloud/page.tsx new file mode 100644 index 00000000000..cc5900e4d15 --- /dev/null +++ b/docs/docs.trychroma.com/app/cloud/page.tsx @@ -0,0 +1,15 @@ +import React from "react"; +import Sidebar from "@/components/sidebar/sidebar"; + +const CloudPage: React.FC = () => { + return ( +
+ +
+

Coming Soon

+
+
+ ); +}; + +export default CloudPage; diff --git a/docs/docs.trychroma.com/public/favicon.ico b/docs/docs.trychroma.com/app/favicon.ico similarity index 100% rename from docs/docs.trychroma.com/public/favicon.ico rename to docs/docs.trychroma.com/app/favicon.ico diff --git a/docs/docs.trychroma.com/app/fonts/GeistMonoVF.woff b/docs/docs.trychroma.com/app/fonts/GeistMonoVF.woff new file mode 100644 index 00000000000..f2ae185cbfd Binary files /dev/null and b/docs/docs.trychroma.com/app/fonts/GeistMonoVF.woff differ diff --git a/docs/docs.trychroma.com/app/fonts/GeistVF.woff b/docs/docs.trychroma.com/app/fonts/GeistVF.woff new file mode 100644 index 00000000000..1b62daacff9 Binary files /dev/null and b/docs/docs.trychroma.com/app/fonts/GeistVF.woff differ diff --git a/docs/docs.trychroma.com/app/globals.css b/docs/docs.trychroma.com/app/globals.css new file mode 100644 index 00000000000..6d893b831af --- /dev/null +++ b/docs/docs.trychroma.com/app/globals.css @@ -0,0 +1,20 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +body { + font-family: Arial, Helvetica, sans-serif; + @apply text-[#27201C] dark:text-white +} + +@layer utilities { + .text-balance { + text-wrap: balance; + } +} + +@layer base { + :root { + --radius: 0.5rem; + } +} diff --git a/docs/docs.trychroma.com/app/layout.tsx b/docs/docs.trychroma.com/app/layout.tsx new file mode 100644 index 00000000000..9856e1e97b0 --- /dev/null +++ b/docs/docs.trychroma.com/app/layout.tsx @@ -0,0 +1,43 @@ +import type { Metadata } from "next"; +import "./globals.css"; +import React from "react"; +import ThemeProvider from "@/components/ui/theme-provider"; +import { Inter } from "next/font/google"; +import Header from "@/components/header/header"; +import PostHogProvider from "@/components/posthog/posthog-provider"; + +export const metadata: Metadata = { + title: "Chroma Docs", + description: "Documentation for ChromaDB", +}; + +const inter = Inter({ subsets: ["latin"] }); + +export default function RootLayout({ + children, +}: Readonly<{ + children: React.ReactNode; +}>) { + return ( + + + + +
+
+
+
+ {children} +
+
+ + + + + ); +} diff --git a/docs/docs.trychroma.com/app/not-found.tsx b/docs/docs.trychroma.com/app/not-found.tsx new file mode 100644 index 00000000000..32c601f0168 --- /dev/null +++ b/docs/docs.trychroma.com/app/not-found.tsx @@ -0,0 +1,19 @@ +import React from "react"; +import CodeBlock from "@/components/markdoc/code-block"; + +const notFoundCode = ` +import chromadb + +client = chromadb.Client() +collection = client.get_collection(name="chroma_docs") +results = collection.get(ids=["page"])["documents"] +print(results) # Not found [] +` + +const NotFound = () => { + return
+ +
+} + +export default NotFound; \ No newline at end of file diff --git a/docs/docs.trychroma.com/app/page.tsx b/docs/docs.trychroma.com/app/page.tsx new file mode 100644 index 00000000000..310aabff76d --- /dev/null +++ b/docs/docs.trychroma.com/app/page.tsx @@ -0,0 +1,5 @@ +import { redirect } from "next/navigation"; + +export default function Home() { + return redirect("/docs/overview/introduction"); +} diff --git a/docs/docs.trychroma.com/components.json b/docs/docs.trychroma.com/components.json index 3011c6a3cc5..88a579834c9 100644 --- a/docs/docs.trychroma.com/components.json +++ b/docs/docs.trychroma.com/components.json @@ -1,17 +1,20 @@ { "$schema": "https://ui.shadcn.com/schema.json", "style": "new-york", - "rsc": false, + "rsc": true, "tsx": true, "tailwind": { - "config": "tailwind.config.js", - "css": "public/globals.css", - "baseColor": "slate", - "cssVariables": true, + "config": "tailwind.config.ts", + "css": "app/globals.css", + "baseColor": "zinc", + "cssVariables": false, "prefix": "" }, "aliases": { - "components": "components", - "utils": "lib/utils" + "components": "@/components", + "utils": "@/lib/utils", + "ui": "@/components/ui", + "lib": "@/lib", + "hooks": "@/hooks" } -} +} \ No newline at end of file diff --git a/docs/docs.trychroma.com/components/CodeBlock.tsx b/docs/docs.trychroma.com/components/CodeBlock.tsx deleted file mode 100644 index 6213afc64cb..00000000000 --- a/docs/docs.trychroma.com/components/CodeBlock.tsx +++ /dev/null @@ -1,194 +0,0 @@ - -import * as React from 'react'; -import CopyToClipboardButton from './CopyToClipboardButton'; -import { useTheme } from 'next-themes'; -import { useRouter } from 'next/router'; - -import Prism from 'prismjs'; -require(`prismjs/components/prism-python.min.js`); -require(`prismjs/components/prism-bash.min.js`); -require(`prismjs/components/prism-javascript.min.js`); -require(`prismjs/components/prism-typescript.min.js`); -require(`prismjs/components/prism-yaml.js`); -require(`prismjs/components/prism-json.min.js`); - -Prism.languages.python = { - ...Prism.languages.python, - 'class-name': /\b[A-Z]\w+/, - - 'function': { - pattern: /(\b\w+\.)?\w+(?=\s*\()/, - // lookbehind: true, - inside: { - 'class': /^[^.]*\./, - 'punctuation': /\./, - 'method': { - pattern: /\w+$/, - alias: 'function' - }, - - }, - } - -}; - -import { Icons } from './ui/icons'; - -interface CodeBlockProps { - children: string; - 'data-language': string; - filename?: string; - obfuscated?: boolean; - codetab?: boolean; -} - -export function CodeBlock({children, 'data-language': language, filename, codetab}: CodeBlockProps) { - const ref = React.useRef(null); - - if (!language) { - language = 'plaintext'; - } - - if (language === 'py') { - language = 'python'; - } - - const [highlightedCode, setHighlightedCode] = React.useState(''); - const [codeWithoutSyntax, setCodeWithoutSyntax] = React.useState(''); - var code$Regex = /^(.*?)#\s*\[\!code\s*\$\]\s*(.*)$/; - - // children without code$Regex - // iterate over the children and remove the code$Regex - let newChildren = children.split('\n').map((line) => { - let match = line.match(code$Regex); - if (match) { - return match[1].trim() - } - return line - }).join('\n') - - React.useEffect(() => { - async function highlight() { - - if (language === 'sh') { - language = 'bash' - } - - Prism.hooks.add(`after-highlight`, function (env) { - // Split the highlighted HTML by line breaks into an array of lines - var lines = env.highlightedCode.split('\n').slice(0, -1); // slice to remove the last empty line - - var wrappedLines = lines.map(function(line) { - // Regex to match the marker with flexible whitespace - - var match = line.match(code$Regex); - if (match) { - // If it does, remove the marker and wrap the line with div.line and add the class - // `match[1]` contains the line without the marker - return '
' + match[1].trim() + '
'; - } else { - // Otherwise, just wrap the line with div.line - return '
' + line + '
'; - } - - }).join(''); - - // Replace the highlightedCode with the wrapped lines - env.element.innerHTML = wrappedLines; - }) - - const env = { - element: {}, - language, - grammar: Prism.languages[language], - highlightedCode: undefined, - code: children - }; - - Prism.hooks.run('before-highlight', env); - env.highlightedCode = Prism.highlight(env.code, env.grammar, env.language); - Prism.hooks.run('before-insert', env); - // @ts-ignore - env.element.innerHTML = env.highlightedCode; - Prism.hooks.run('after-highlight', env); - Prism.hooks.run('complete', env); - - // const highlightedCode = Prism.highlight(children, Prism.languages[language], language); - // Prism.hooks.run('before-tokenize', highlightedCode); - - // @ts-ignore - setHighlightedCode(env.element.innerHTML); - } - - highlight(); - }, [children]); - - let copyIconColor = 'text-gray-500 hover:text-white' - let copyButtonTop = '4px' - - let marginBottom = '1rem' - if (codetab == true) { - marginBottom = '0' - copyButtonTop = '-71px' - } - - return ( -
- - -
-        
-        
-      
- -
- ); -} - -// react component for CustomHeader - -export function CustomHeader({language, filename, codetab}) { - let customHeader = (<>) - - if ((language === 'bash') || (language === 'sh')) { - customHeader = ( -
- -

Command Line

-
- ) - } - - if ((filename)) { - customHeader = ( -
- -

{filename}

-
- ) - } - - // if filename is not provided, then fall back to the language - if ((!filename) && (language !== 'bash') && (language !== 'sh')) { - - // if js, then change to javascript - if (language === 'js') { - language = 'javascript' - } - - customHeader = ( -
- -

{language}

-
- ) - } - - if (codetab == true) { - customHeader = (<>) - } - - return customHeader -} diff --git a/docs/docs.trychroma.com/components/CopyToClipboardButton.tsx b/docs/docs.trychroma.com/components/CopyToClipboardButton.tsx deleted file mode 100644 index ca51a56592e..00000000000 --- a/docs/docs.trychroma.com/components/CopyToClipboardButton.tsx +++ /dev/null @@ -1,49 +0,0 @@ -import React, { useState } from 'react'; -import { Icons } from './ui/icons'; -import { useToast } from './ui/use-toast'; - -const CopyToClipboardButton: React.FC<{ textToCopy: string, className: string, customStyle: any}> = ({ textToCopy, className, customStyle }) => { - const [isCopied, setIsCopied] = useState(false); - - if (customStyle === undefined) { - customStyle = {}; - } - - const {toast} = useToast() - - const copyToClipboard = () => { - const textArea = document.createElement('textarea'); - textArea.value = textToCopy; - document.body.appendChild(textArea); - textArea.select(); - - try { - document.execCommand('copy'); - setIsCopied(true); - } catch (err) { - console.error('Unable to copy to clipboard'); - } finally { - document.body.removeChild(textArea); - } - - toast({ - title: "Copied to clipboard", - }) - - setTimeout(() => { - setIsCopied(false); - }, 2000); - }; - - var copyText = isCopied ? 'Copied!' : 'Copy Code'; - - return ( -
- -
- ); -}; - -export default CopyToClipboardButton; diff --git a/docs/docs.trychroma.com/components/header/discord-link.tsx b/docs/docs.trychroma.com/components/header/discord-link.tsx new file mode 100644 index 00000000000..6d8b4cd7122 --- /dev/null +++ b/docs/docs.trychroma.com/components/header/discord-link.tsx @@ -0,0 +1,29 @@ +import React from "react"; +import Link from "next/link"; +import UIButton from "@/components/ui/ui-button"; +import { DiscordLogoIcon } from "@radix-ui/react-icons"; + +const DiscordLink: React.FC = async () => { + const response = await fetch( + `https://discord.com/api/guilds/1073293645303795742/widget.json`, + { next: { revalidate: 3600 } }, + ); + const onlineUsers = response.ok + ? (await response.json()).presence_count + : undefined; + + return ( + + + + {onlineUsers ? `${onlineUsers} online` : undefined} + + + ); +}; + +export default DiscordLink; diff --git a/docs/docs.trychroma.com/components/header/github-link.tsx b/docs/docs.trychroma.com/components/header/github-link.tsx new file mode 100644 index 00000000000..e7060fe6d60 --- /dev/null +++ b/docs/docs.trychroma.com/components/header/github-link.tsx @@ -0,0 +1,29 @@ +import React from "react"; +import UIButton from "@/components/ui/ui-button"; +import { GitHubLogoIcon } from "@radix-ui/react-icons"; +import { formatToK } from "@/lib/utils"; +import Link from "next/link"; + +const GithubLink: React.FC = async () => { + const response = await fetch( + `https://api.github.com/repos/chroma-core/chroma`, + ); + const stars = response.ok + ? (await response.json()).stargazers_count + : undefined; + + return ( + + + + {stars && formatToK(stars)} + + + ); +}; + +export default GithubLink; diff --git a/docs/docs.trychroma.com/components/header/header.tsx b/docs/docs.trychroma.com/components/header/header.tsx new file mode 100644 index 00000000000..087fbc4fbd4 --- /dev/null +++ b/docs/docs.trychroma.com/components/header/header.tsx @@ -0,0 +1,29 @@ +import React from "react"; +import Logo from "@/components/header/logo"; +import ThemeToggle from "@/components/header/theme-toggle"; +import GithubLink from "@/components/header/github-link"; +import XLink from "@/components/header/x-link"; +import DiscordLink from "@/components/header/discord-link"; +import Link from "next/link"; +import SearchBox from "@/components/header/search-box"; + +const Header: React.FC = () => { + return ( +
+
+ + + + +
+
+ + + + +
+
+ ); +}; + +export default Header; diff --git a/docs/docs.trychroma.com/components/header/language-toggle.tsx b/docs/docs.trychroma.com/components/header/language-toggle.tsx new file mode 100644 index 00000000000..444ef4f7910 --- /dev/null +++ b/docs/docs.trychroma.com/components/header/language-toggle.tsx @@ -0,0 +1,41 @@ +"use client"; + +import React, { useState } from "react"; +import PythonLogo from "../../public/python.svg"; +import TypeScriptLogo from "../../public/typescript.svg"; +import UIButton from "@/components/ui/ui-button"; + +const supportedLanguages: { + [language: string]: React.FC>; +} = { + python: PythonLogo, + typescript: TypeScriptLogo, +}; + +const LanguageToggle: React.FC = () => { + const [preferredLanguage, setPreferredLanguage] = useState("python"); + + const switchLanguage = (language: string) => { + setPreferredLanguage(language); + }; + + return ( +
+ {Object.keys(supportedLanguages).map((language) => { + const Logo = supportedLanguages[language]; + const selected = preferredLanguage === language; + return ( + + + + ); + })} +
+ ); +}; + +export default LanguageToggle; diff --git a/docs/docs.trychroma.com/components/header/logo.tsx b/docs/docs.trychroma.com/components/header/logo.tsx new file mode 100644 index 00000000000..4cf58705441 --- /dev/null +++ b/docs/docs.trychroma.com/components/header/logo.tsx @@ -0,0 +1,16 @@ +import React from "react"; +import ChromaLogo from "../../public/chroma-workmark-color-128.svg"; +import OutlineLogo from "../../public/chroma-wordmark-white-128.svg"; + +const Logo: React.FC = () => { + const logoClass = "w-28 h-10"; + + return ( +
+ +
+ ); +}; + +export default Logo; diff --git a/docs/docs.trychroma.com/components/header/search-box.tsx b/docs/docs.trychroma.com/components/header/search-box.tsx new file mode 100644 index 00000000000..b1ea1a09a7b --- /dev/null +++ b/docs/docs.trychroma.com/components/header/search-box.tsx @@ -0,0 +1,18 @@ +"use client"; + +import React from "react"; +import { DocSearch } from "@docsearch/react"; +import "@docsearch/css"; + +const SearchBox: React.FC = () => { + return ( + + ); +}; + +export default SearchBox; diff --git a/docs/docs.trychroma.com/components/header/sidebar-toggle.tsx b/docs/docs.trychroma.com/components/header/sidebar-toggle.tsx new file mode 100644 index 00000000000..24aac35b85d --- /dev/null +++ b/docs/docs.trychroma.com/components/header/sidebar-toggle.tsx @@ -0,0 +1,21 @@ +import React from "react"; +import { Drawer, DrawerContent, DrawerTrigger } from "@/components/ui/drawer"; +import Sidebar from "@/components/sidebar/sidebar"; +import { SidebarIcon } from "lucide-react"; + +const SidebarToggle: React.FC<{ path: string[] }> = ({ path }) => { + return ( + + +
+ +
+
+ + + +
+ ); +}; + +export default SidebarToggle; diff --git a/docs/docs.trychroma.com/components/header/theme-toggle.tsx b/docs/docs.trychroma.com/components/header/theme-toggle.tsx new file mode 100644 index 00000000000..8eb5ccc2b48 --- /dev/null +++ b/docs/docs.trychroma.com/components/header/theme-toggle.tsx @@ -0,0 +1,29 @@ +"use client"; + +import * as React from "react"; +import { Moon, Sun } from "lucide-react"; +import { useTheme } from "next-themes"; + +import UIButton from "@/components/ui/ui-button"; + +const ThemeToggle = () => { + const { theme, setTheme } = useTheme(); + + const toggleTheme = () => { + if (theme === "dark") { + setTheme("light"); + } else { + setTheme("dark"); + } + }; + + return ( + + + + Toggle theme + + ); +}; + +export default ThemeToggle; diff --git a/docs/docs.trychroma.com/components/header/x-link.tsx b/docs/docs.trychroma.com/components/header/x-link.tsx new file mode 100644 index 00000000000..e627c3c2b91 --- /dev/null +++ b/docs/docs.trychroma.com/components/header/x-link.tsx @@ -0,0 +1,21 @@ +import React from "react"; +import Link from "next/link"; +import UIButton from "@/components/ui/ui-button"; +import XLogo from "../../public/x-logo.svg"; + +const XLink: React.FC = () => { + return ( + + + +

17.7k

+
+ + ); +}; + +export default XLink; diff --git a/docs/docs.trychroma.com/components/layout/SideNav.tsx b/docs/docs.trychroma.com/components/layout/SideNav.tsx deleted file mode 100644 index 3d6e92d9009..00000000000 --- a/docs/docs.trychroma.com/components/layout/SideNav.tsx +++ /dev/null @@ -1,142 +0,0 @@ -import React from 'react'; -import { useRouter } from 'next/router'; -import Link from 'next/link'; - -import { - DropdownMenu, - DropdownMenuContent, - DropdownMenuItem, - DropdownMenuLabel, - DropdownMenuSeparator, - DropdownMenuTrigger, -} from "../ui/dropdown-menu" - -interface LinkItem { - href: string; - children: React.ReactNode; -} - -interface SideNavItem { - title: string; - links: LinkItem[]; -} - -interface SidebarNavItemFlat { - title: string; - href: string; - children: React.ReactNode; - type: string; -} - -const ROOT_ITEMS = require(`../../pages/_sidenav.js`).items; - -export function SideNav() { - const router = useRouter(); - - // Dynamically import the sidenav configuration based on the current path - // Assuming the items are of type SideNavItem[] - let pathVar = router.asPath.split('/')[1] !== undefined ? router.asPath.split('/')[1] : ''; - pathVar = pathVar.split('?')[0]; - - let group = false - let groupObject = null - // iterate through ROOT_ITEMS to see if pathVar is a group or not - // this tell us whether to show the root items or the group items - ROOT_ITEMS.map((item: SidebarNavItemFlat) => { - if (item.href === `/${pathVar}` && item.type === 'group') { - group = true - groupObject = item - } - }) - - pathVar = (pathVar !== "") ? pathVar + '/' : pathVar; - if (!group) pathVar = ''; - const items: (SideNavItem[] | SidebarNavItemFlat[]) = require(`../../pages/${pathVar}_sidenav.js`).items; - - const navToURL = (url: string) => { - router.push(url); - } - - return ( - <> - - - - ); -} - -// SideNav Link component -export const SideNavLink = ({ href, title }) => { - const router = useRouter(); - const activeClass = `sideNavItemActive rounded-md font-medium text-md` - return ( - - {title} - - ); -} diff --git a/docs/docs.trychroma.com/components/layout/TableOfContents.tsx b/docs/docs.trychroma.com/components/layout/TableOfContents.tsx deleted file mode 100644 index 0d9d338fa80..00000000000 --- a/docs/docs.trychroma.com/components/layout/TableOfContents.tsx +++ /dev/null @@ -1,65 +0,0 @@ -import React, { useEffect, useState } from 'react'; -import Link from 'next/link'; - -interface TOCItem { - id: string; - level: number; - title: string; -} - -interface TableOfContentsProps { - toc: TOCItem[]; -} - -export function TableOfContents({ toc }: TableOfContentsProps) { - - const [items, setItems] = useState([]); - - useEffect(() => { - setItems(toc); - }, [toc]); - - // for each item, look for it in the DOM and make sure that it is not hidden - // this enables hiding headings that are hidden from tab state - let visibleItems = []; - items.forEach((item) => { - const el = document.getElementById(item.id); - // if el is null, cull from items - if (el !== null) { - visibleItems.push(item); - } - }); - - // get the minimum level across all items to left align well - const minLevel = Math.min(...items.map((item) => item.level)); - - return ( - - ); -} diff --git a/docs/docs.trychroma.com/components/layout/TopNav.tsx b/docs/docs.trychroma.com/components/layout/TopNav.tsx deleted file mode 100644 index 7293ad8f70b..00000000000 --- a/docs/docs.trychroma.com/components/layout/TopNav.tsx +++ /dev/null @@ -1,43 +0,0 @@ -import React, { useState, ReactNode } from "react"; -import Link from "next/link"; // Assuming you're using Next.js Link, make sure to import it. - -interface TopNavProps { - children: ReactNode; // This type accepts anything that can be rendered: numbers, strings, elements or an array containing these types. -} - -import "@docsearch/css"; -import { DocSearch } from "@docsearch/react"; - -export function TopNav({ children }: TopNavProps) { - return ( -
- -
- ); -} - -function Search() { - return ( - - ); -} diff --git a/docs/docs.trychroma.com/components/layout/state.tsx b/docs/docs.trychroma.com/components/layout/state.tsx deleted file mode 100644 index 2b790c726b0..00000000000 --- a/docs/docs.trychroma.com/components/layout/state.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import React, { createContext, useContext, useEffect, useState } from 'react'; - -// Create a context with a default empty state -export const GlobalStateContext = createContext({ - globalStateObject: {}, - setGlobalStateObject: (state: {}) => {}, -}); - -export const GlobalStateProvider = ({ children }) => { - const [globalStateObject, setGlobalStateObject] = useState(() => { - - let initialState = { 'code-lang': 'python' }; - - if (typeof window !== 'undefined') { - // Attempt to read from local storage - const localState = localStorage.getItem('globalState'); - let localStateObj = {}; - if (localState) { - localStateObj = JSON.parse(localState); - } - - // Merge local storage and query params - initialState = { ...initialState, ...localStateObj}; - } - - return initialState; - }); - - useEffect(() => { - // Ensure window is defined before attempting to use localStorage - if (typeof window !== 'undefined') { - localStorage.setItem('globalState', JSON.stringify(globalStateObject)); - } - - }, [globalStateObject]); - - return ( - - {children} - - ); -}; diff --git a/docs/docs.trychroma.com/components/markdoc/AppLink.tsx b/docs/docs.trychroma.com/components/markdoc/AppLink.tsx deleted file mode 100644 index 53e7cd2cdc7..00000000000 --- a/docs/docs.trychroma.com/components/markdoc/AppLink.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import React from 'react'; -import Link from 'next/link'; - -export function AppLink(props) { - return ( - - {props.children} - - ); -} diff --git a/docs/docs.trychroma.com/components/markdoc/CodeTab.tsx b/docs/docs.trychroma.com/components/markdoc/CodeTab.tsx deleted file mode 100644 index 9b31678e9ba..00000000000 --- a/docs/docs.trychroma.com/components/markdoc/CodeTab.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import React, { ReactNode } from 'react'; -import { TabsContent } from "../ui/tabs" -import slugify from '@sindresorhus/slugify'; - -interface TabProps { - label: string; - children: ReactNode; -} - -export function CodeTab({ label, children }: TabProps) { - return {children} -} diff --git a/docs/docs.trychroma.com/components/markdoc/CodeTabs.tsx b/docs/docs.trychroma.com/components/markdoc/CodeTabs.tsx deleted file mode 100644 index be2ede34ac4..00000000000 --- a/docs/docs.trychroma.com/components/markdoc/CodeTabs.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import React, { createContext, useContext, useState, ReactNode, useEffect, FC } from 'react'; -import { GlobalStateContext } from '../layout/state'; -import { Tabs as ShadTabs, TabsList, TabsTrigger } from "../ui/tabs" -import slugify from '@sindresorhus/slugify'; -import { CustomHeader } from '../CodeBlock'; - -// Define the props for the Tabs component -interface TabsProps { - labels: string[]; - children: ReactNode; - customHeader?: string; -} - -export const CodeTabs: FC = ({ labels, children, customHeader }: TabsProps) => { - - let defaultValue = labels[0] || ''; - if (!customHeader) { - customHeader = ''; - } - - return ( -
- - - -
    - {labels.map((label) => ( - {label} - ))} -
-
- {children} -
-
- ); -}; diff --git a/docs/docs.trychroma.com/components/markdoc/Heading.tsx b/docs/docs.trychroma.com/components/markdoc/Heading.tsx deleted file mode 100644 index 6295aa62e2b..00000000000 --- a/docs/docs.trychroma.com/components/markdoc/Heading.tsx +++ /dev/null @@ -1,67 +0,0 @@ -import * as React from "react"; -import { useRouter } from "next/router"; - -// Define the props type -interface HeadingProps { - id?: string; - level?: 1 | 2 | 3 | 4 | 5 | 6; // assuming level can only be between 1 and 6 - children: React.ReactNode; - className?: string; -} - -export function Heading({ - id = "", - level = 1, - children, - className, -}: HeadingProps) { - const router = useRouter(); - const Component: React.ElementType = `h${level}`; - - const isDocs = router.pathname.startsWith("/docs"); - - if (level === 1) { - className = "text-3xl mb-6 mt-8 font-semibold"; - } - if (level === 2) { - className = "text-2xl mb-4 mt-6 font-semibold"; - } - if (level === 3) { - className = "text-xl mb-4 mt-4 font-semibold"; - } - if (level === 4) { - className = "text-lg mb-4 mt-4 font-semibold"; - } - if (level === 5) { - className = "text-md mb-4 mt-4 font-semibold"; - } - if (level === 6) { - className = "text-sm mb-4 mt-4 font-semibold"; - } - - const link = ( - -
- {children} - ) => { - e.preventDefault(); - navigator.clipboard.writeText( - `${window.location.origin}${router.pathname}#${id}`, - ); - window.history.replaceState( - null, - "", - `${window.location.origin}${router.pathname}#${id}`, - ); - }} - className="text-gray-500 hover:text-gray-700 ml-2 cursor-pointer href-anchor" - > - # - - - ); - - return isDocs && level !== 1 ? {link} : link; -} diff --git a/docs/docs.trychroma.com/components/markdoc/Math.tsx b/docs/docs.trychroma.com/components/markdoc/Math.tsx deleted file mode 100644 index 23b1ba23939..00000000000 --- a/docs/docs.trychroma.com/components/markdoc/Math.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import React from 'react'; -import TeX from '@matejmazur/react-katex'; - -const MathComponent = ({ latexText }) => { - return -}; - -export default MathComponent; diff --git a/docs/docs.trychroma.com/components/markdoc/Note.tsx b/docs/docs.trychroma.com/components/markdoc/Note.tsx deleted file mode 100644 index 5f1dd83bd4a..00000000000 --- a/docs/docs.trychroma.com/components/markdoc/Note.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import React, { ReactNode } from 'react'; -import { Alert, AlertDescription, AlertTitle } from "../../components/ui/alert" -import { Icons } from '../ui/icons'; - -interface NoteProps { - type: 'warning' | 'caution' | 'default' | 'tip'; - title?: string; - children: ReactNode; -} - -export function Note({ type, title, children }: NoteProps) { - - if (!type) type = 'default'; - - let iconFlex = 'items-center'; - if (title !== undefined) iconFlex = 'items-start'; - - return ( - -
- - {(type === 'tip')? : null} - {(type === 'default')? : null} - {(type === 'warning')? : null} - {(type === 'caution')? : null} - -
- {title ? ( - {title} - ) : null} - - {children} - -
-
-
- ) -} diff --git a/docs/docs.trychroma.com/components/markdoc/SpecialTable.tsx b/docs/docs.trychroma.com/components/markdoc/SpecialTable.tsx deleted file mode 100644 index b1f5b037e14..00000000000 --- a/docs/docs.trychroma.com/components/markdoc/SpecialTable.tsx +++ /dev/null @@ -1,3 +0,0 @@ -export function SpecialTable() { - return
- } diff --git a/docs/docs.trychroma.com/components/markdoc/Tab.tsx b/docs/docs.trychroma.com/components/markdoc/Tab.tsx deleted file mode 100644 index f3614f1912e..00000000000 --- a/docs/docs.trychroma.com/components/markdoc/Tab.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import React, { ReactNode } from 'react'; -import { TabsContent } from "../ui/tabs" -import slugify from '@sindresorhus/slugify'; - -interface TabProps { - label: string; - children: ReactNode; -} - -export function Tab({ label, children }: TabProps) { - return {children} -} diff --git a/docs/docs.trychroma.com/components/markdoc/Tabs.tsx b/docs/docs.trychroma.com/components/markdoc/Tabs.tsx deleted file mode 100644 index 6aa7a8136a1..00000000000 --- a/docs/docs.trychroma.com/components/markdoc/Tabs.tsx +++ /dev/null @@ -1,62 +0,0 @@ -import React, { createContext, useContext, useState, ReactNode, useEffect, FC } from 'react'; -import { GlobalStateContext } from '../layout/state'; -import { Tabs as ShadTabs, TabsList, TabsTrigger } from "../ui/tabs" -import slugify from '@sindresorhus/slugify'; - -// Define the props for the Tabs component -interface TabsProps { - labels: string[]; - children: ReactNode; - group?: string; - hideTabs?: boolean; - hideContent?: boolean; -} - -export const Tabs: FC = ({ labels, children, group, hideTabs, hideContent }: TabsProps) => { - const [currentTab, setCurrentTab] = useState(labels[0]); - const [labelsInternal, setLabelsInternal] = useState(labels); - const [createdTime, setCreatedTime] = useState(Date.now()); - - // set labels on init - useEffect(() => { - setLabelsInternal(labels); - }, []); - - const { globalStateObject, setGlobalStateObject } = useContext(GlobalStateContext); - - if (hideTabs === undefined) { - hideTabs = false; - } - if (hideContent === undefined) { - hideContent = false; - } - - // When globalStateObject changes, set the appropriate tab - useEffect(() => { - if (group !== undefined) setCurrentTab(globalStateObject[group]); - }, [globalStateObject]); - - // Function to set the global StateObject and current tab - const setVal = (label: string) => { - if (group !== undefined) setGlobalStateObject({... globalStateObject, [group]: label}); - setCurrentTab(label); - }; - - let defaultValue = labels[0] || ''; - if (group) defaultValue = globalStateObject[group]; - - return ( - - {hideTabs ? null : ( - -
    - {labels.map((label) => ( - setVal(label)}>{label} - ))} -
-
- )} - {hideContent ? null :
{children}
} -
- ); -}; diff --git a/docs/docs.trychroma.com/components/markdoc/banner.tsx b/docs/docs.trychroma.com/components/markdoc/banner.tsx new file mode 100644 index 00000000000..f9268e45fb8 --- /dev/null +++ b/docs/docs.trychroma.com/components/markdoc/banner.tsx @@ -0,0 +1,26 @@ +import React from "react"; +import { InfoCircledIcon } from "@radix-ui/react-icons"; + +const Banner: React.FC<{ type: string; children: React.ReactNode }> = ({ + type, + children, +}) => { + const styles: Record = { + note: "bg-yellow-500", + tip: "bg-blue-500", + warn: "bg-red-500 ", + }; + + return ( +
+
+
+ {children} +
+
+ ); +}; + +export default Banner; diff --git a/docs/docs.trychroma.com/components/markdoc/centered-content.tsx b/docs/docs.trychroma.com/components/markdoc/centered-content.tsx new file mode 100644 index 00000000000..4f37a0b9528 --- /dev/null +++ b/docs/docs.trychroma.com/components/markdoc/centered-content.tsx @@ -0,0 +1,9 @@ +import React from "react"; + +const CenteredContent: React.FC<{ children: React.ReactNode }> = ({ + children, +}) => { + return
{children}
; +}; + +export default CenteredContent; diff --git a/docs/docs.trychroma.com/components/markdoc/code-block-header.tsx b/docs/docs.trychroma.com/components/markdoc/code-block-header.tsx new file mode 100644 index 00000000000..2f6c8399581 --- /dev/null +++ b/docs/docs.trychroma.com/components/markdoc/code-block-header.tsx @@ -0,0 +1,24 @@ +import React from "react"; +import { Playfair_Display } from "next/font/google"; +import CopyButton from "@/components/markdoc/copy-button"; +import { capitalize } from "@/lib/utils"; + +export const tabLabelStyle = `rounded-none px-4 py-2 text-xs font-medium tracking-wider border-b-[1px] border-transparent disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-transparent data-[state=active]:text-chroma-orange data-[state=active]:shadow-none data-[state=active]:border-chroma-orange cursor-pointer select-none font-mono tracking-tight`; + +const CodeBlockHeader: React.FC<{ + language: string; + content: string; +}> = ({ language, content }) => { + return ( +
+
+ {capitalize(language)} +
+
+ +
+
+ ); +}; + +export default CodeBlockHeader; diff --git a/docs/docs.trychroma.com/components/markdoc/code-block.tsx b/docs/docs.trychroma.com/components/markdoc/code-block.tsx new file mode 100644 index 00000000000..d3f635a1f42 --- /dev/null +++ b/docs/docs.trychroma.com/components/markdoc/code-block.tsx @@ -0,0 +1,58 @@ +import React from "react"; +import { unified } from "unified"; +import parse from "remark-parse"; +import rehypeHighlight from "rehype-highlight"; +import remarkRehype from "remark-rehype"; +import rehypeStringify from "rehype-stringify"; +import { visit } from "unist-util-visit"; +import CodeBlockHeader from "@/components/markdoc/code-block-header"; + +import "highlight.js/styles/atom-one-dark.css"; + +const rehypeRemovePre = () => { + return (tree: any) => { + visit(tree, "element", (node) => { + if (node.tagName === "pre" && node.children.length) { + const codeNode = node.children.find( + (child: { tagName: string }) => child.tagName === "code", + ); + if (codeNode) { + node.tagName = "code"; + node.children = codeNode.children; + } + } + }); + }; +}; + +const CodeBlock: React.FC<{ + content: React.ReactNode; + language: string; + showHeader: boolean; + className?: string; +}> = async ({ content, language, showHeader = true, className }) => { + if (typeof content !== "string") { + throw new Error("CodeBlock children must be a string."); + } + + const highlightedCode = await unified() + .use(parse) + .use(remarkRehype) + .use(rehypeHighlight, { subset: [language] }) + .use(rehypeRemovePre) + .use(rehypeStringify) + .process(`\`\`\`${language}\n${content}\`\`\``); + + return ( +
+ {showHeader && language && ( + + )} +
+        
+
+
+ ); +}; + +export default CodeBlock; diff --git a/docs/docs.trychroma.com/components/markdoc/code-tab.tsx b/docs/docs.trychroma.com/components/markdoc/code-tab.tsx new file mode 100644 index 00000000000..a4a4d72db9a --- /dev/null +++ b/docs/docs.trychroma.com/components/markdoc/code-tab.tsx @@ -0,0 +1,16 @@ +"use client"; + +import React, { useContext } from "react"; +import AppContext from "@/context/app-context"; +import { Tabs } from "@/components/ui/tabs"; + +const CodeTabs: React.FC<{ children: React.ReactNode }> = ({ children }) => { + const { language } = useContext(AppContext); + return ( + + {children} + + ); +}; + +export default CodeTabs; diff --git a/docs/docs.trychroma.com/components/markdoc/copy-button.tsx b/docs/docs.trychroma.com/components/markdoc/copy-button.tsx new file mode 100644 index 00000000000..3950dc17c2a --- /dev/null +++ b/docs/docs.trychroma.com/components/markdoc/copy-button.tsx @@ -0,0 +1,47 @@ +"use client"; + +import React, { useState } from "react"; +import { + Tooltip, + TooltipContent, + TooltipProvider, + TooltipTrigger, +} from "@/components/ui/tooltip"; +import { CopyIcon } from "lucide-react"; + +const CopyButton: React.FC<{ content: string }> = ({ content }) => { + const [copied, setCopied] = useState(false); + const [open, setOpen] = useState(false); + + const handleCopy = () => { + navigator.clipboard.writeText(content).then(() => { + setCopied(true); + setTimeout(() => setCopied(false), 2000); + }); + }; + + return ( + + + setOpen(true)} + onMouseLeave={() => setOpen(false)} + > + + + +

{copied ? "Copied!" : "Copy"}

+
+
+
+ ); +}; + +export default CopyButton; diff --git a/docs/docs.trychroma.com/components/markdoc/inline-code.tsx b/docs/docs.trychroma.com/components/markdoc/inline-code.tsx new file mode 100644 index 00000000000..cc023c22a9d --- /dev/null +++ b/docs/docs.trychroma.com/components/markdoc/inline-code.tsx @@ -0,0 +1,11 @@ +import React from "react"; + +const InlineCode: React.FC<{ content: React.ReactNode }> = ({ content }) => { + return ( + + {content} + + ); +}; + +export default InlineCode; diff --git a/docs/docs.trychroma.com/components/markdoc/latex.tsx b/docs/docs.trychroma.com/components/markdoc/latex.tsx new file mode 100644 index 00000000000..9154dfeac7a --- /dev/null +++ b/docs/docs.trychroma.com/components/markdoc/latex.tsx @@ -0,0 +1,23 @@ +import React from "react"; +import katex from 'katex'; +import 'katex/dist/katex.min.css'; + +const Latex:React.FC<{children: React.ReactNode}> = ({children}) => { + const content = React.Children.toArray(children).join(''); + try { + return ( + + ); + } catch (error) { + console.error(error); + return Error rendering LaTeX; + } +} + +export default Latex; \ No newline at end of file diff --git a/docs/docs.trychroma.com/components/markdoc/markdoc-heading.tsx b/docs/docs.trychroma.com/components/markdoc/markdoc-heading.tsx new file mode 100644 index 00000000000..09da191177b --- /dev/null +++ b/docs/docs.trychroma.com/components/markdoc/markdoc-heading.tsx @@ -0,0 +1,38 @@ +import React from "react"; + +const generateId = (content: React.ReactNode): string => { + if (typeof content === "string") { + return content + .toLowerCase() + .replace(/[^a-z0-9\s-]/g, "") + .replace(/\s+/g, "-") + .trim(); + } + return ""; +}; + +const Heading: React.FC<{ + level: number; + children: React.ReactNode; + id?: string; +}> = ({ level, children, id }) => { + const HeadingTag: React.ElementType = `h${level}` as React.ElementType; + const headingId = id || generateId(children); + + return ( + + {children} + {headingId && level === 2 && ( + + # + + )} + + ); +}; + +export default Heading; diff --git a/docs/docs.trychroma.com/components/markdoc/markdoc-image.tsx b/docs/docs.trychroma.com/components/markdoc/markdoc-image.tsx new file mode 100644 index 00000000000..fa71448cf9a --- /dev/null +++ b/docs/docs.trychroma.com/components/markdoc/markdoc-image.tsx @@ -0,0 +1,17 @@ +import React from "react"; +import Image from "next/image"; +import { imageSize } from "image-size"; + +const MarkdocImage: React.FC<{ src: string; alt: string; title?: string }> = ({ + src, + alt, +}) => { + try { + const { width, height } = imageSize(`public/${src}`); + return {alt}; + } catch (e) { + return
; + } +}; + +export default MarkdocImage; diff --git a/docs/docs.trychroma.com/components/markdoc/markdoc-page.tsx b/docs/docs.trychroma.com/components/markdoc/markdoc-page.tsx new file mode 100644 index 00000000000..57eb53bf1cf --- /dev/null +++ b/docs/docs.trychroma.com/components/markdoc/markdoc-page.tsx @@ -0,0 +1,18 @@ +"use client"; + +import React, { Suspense } from "react"; +import { AppContextProvider } from "@/context/app-context"; + +const MarkdocPage: React.FC<{ children: React.ReactNode }> = ({ children }) => { + return ( + + +
+
{children}
+
+
+
+ ); +}; + +export default MarkdocPage; diff --git a/docs/docs.trychroma.com/components/markdoc/markdoc-renderer.tsx b/docs/docs.trychroma.com/components/markdoc/markdoc-renderer.tsx new file mode 100644 index 00000000000..5329e8973a6 --- /dev/null +++ b/docs/docs.trychroma.com/components/markdoc/markdoc-renderer.tsx @@ -0,0 +1,64 @@ +import fs from "fs"; +import path from "path"; +import React from "react"; +import Markdoc from "@markdoc/markdoc"; +import markdocConfig from "@/markdoc/config"; +import { notFound } from "next/navigation"; +import MarkdocPage from "@/components/markdoc/markdoc-page"; +import SidebarToggle from "@/components/header/sidebar-toggle"; +import { GitHubLogoIcon } from "@radix-ui/react-icons"; +import Link from "next/link"; +import { getAllPages, getPagePrevNext } from "@/lib/content"; +import sidebarConfig from "@/markdoc/content/sidebar-config"; +import PageNav from "@/components/markdoc/page-nav"; + +const MarkdocRenderer: React.FC<{ slug: string[] }> = ({ slug }) => { + const filePath = `${path.join(process.cwd(), "markdoc", "content", ...slug)}.md`; + + if (!fs.existsSync(filePath)) { + notFound(); + } + + const source = fs.readFileSync(filePath, "utf-8"); + + const ast = Markdoc.parse(source); + const content = Markdoc.transform(ast, markdocConfig); + + const output = Markdoc.renderers.react(content, React, { + components: markdocConfig.components, + }); + + const GitHubLink = `https://github.com/chroma-core/chroma/tree/main/docs/docs.trychroma.com/markdoc/content/${slug.join("/")}.md`; + + const { prev, next } = getPagePrevNext( + slug, + getAllPages(sidebarConfig, slug[0]), + ); + + return ( + +
+ + {output} +
+ {prev ? ( + + ) : ( +
+ )} + {next ? ( + + ) : ( +
+ )} +
+
+ + Edit this page on GitHub +
+
+ + ); +}; + +export default MarkdocRenderer; diff --git a/docs/docs.trychroma.com/components/markdoc/misc.tsx b/docs/docs.trychroma.com/components/markdoc/misc.tsx deleted file mode 100644 index 0dd480614cb..00000000000 --- a/docs/docs.trychroma.com/components/markdoc/misc.tsx +++ /dev/null @@ -1,3 +0,0 @@ -export function Br() { - return
-} diff --git a/docs/docs.trychroma.com/components/markdoc/page-nav.tsx b/docs/docs.trychroma.com/components/markdoc/page-nav.tsx new file mode 100644 index 00000000000..19dd4fa8a14 --- /dev/null +++ b/docs/docs.trychroma.com/components/markdoc/page-nav.tsx @@ -0,0 +1,37 @@ +"use client"; + +import React from "react"; +import Link from "next/link"; +import { ArrowLeft, ArrowRight } from "lucide-react"; + +const PageNav: React.FC<{ + path: string; + name: string; + type: "prev" | "next"; +}> = ({ path, name, type }) => { + return ( + { + sessionStorage.removeItem("sidebarScrollPosition"); + }} + > +
+ {type === "prev" && ( + <> + +

{name}

+ + )} + {type === "next" && ( + <> +

{name}

+ + + )} +
+ + ); +}; + +export default PageNav; diff --git a/docs/docs.trychroma.com/components/markdoc/tabbed-code-block.tsx b/docs/docs.trychroma.com/components/markdoc/tabbed-code-block.tsx new file mode 100644 index 00000000000..2aa58fa5586 --- /dev/null +++ b/docs/docs.trychroma.com/components/markdoc/tabbed-code-block.tsx @@ -0,0 +1,69 @@ +import React, { ReactElement } from "react"; +import CopyButton from "@/components/markdoc/copy-button"; +import { TabsContent, TabsList } from "@/components/ui/tabs"; +import { tabLabelStyle } from "@/components/markdoc/code-block-header"; +import { capitalize, cn } from "@/lib/utils"; +import CodeBlock from "@/components/markdoc/code-block"; +import { TabProps, TabsTrigger } from "@/components/markdoc/tabs"; +import CodeTabs from "@/components/markdoc/code-tab"; + +const TabbedCodeBlock: React.FC<{ + children: ReactElement[]; +}> = ({ children }) => { + const tabs = children.map((tab) => { + return { + label: tab.props.label, + content: tab.props.children.props.content, + render: + tab.props.children.type === CodeBlock + ? React.cloneElement(tab, { + children: React.cloneElement(tab.props.children, { + showHeader: false, + }), + }) + : tab, + }; + }); + + return ( + +
+ + {tabs.map((tab) => ( + + {capitalize(tab.label)} + + ))} + +
+ {tabs.map((tab) => ( + + + + ))} +
+
+
+ {tabs.map((tab) => ( + + {tab.render} + + ))} +
+
+ ); +}; + +export default TabbedCodeBlock; diff --git a/docs/docs.trychroma.com/components/markdoc/tabbed-use-case-code-block.tsx b/docs/docs.trychroma.com/components/markdoc/tabbed-use-case-code-block.tsx new file mode 100644 index 00000000000..446d8b6486b --- /dev/null +++ b/docs/docs.trychroma.com/components/markdoc/tabbed-use-case-code-block.tsx @@ -0,0 +1,68 @@ +import React, { ReactElement } from "react"; +import { tabLabelStyle } from "@/components/markdoc/code-block-header"; +import { capitalize, cn } from "@/lib/utils"; +import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; +import { TabProps } from "@/components/markdoc/tabs"; +import CodeBlock from "@/components/markdoc/code-block"; +import CopyButton from "@/components/markdoc/copy-button"; + +const TabbedUseCaseCodeBlock: React.FC<{ + language: string; + children: ReactElement[]; +}> = ({ language, children }) => { + return ( + +
+
+
+ {capitalize(language)} +
+ + {children.map((tab) => ( + + {tab.props.label} + + ))} + +
+
+ {children.map((tab) => ( + + + + ))} +
+
+
+ {children.map((tab) => ( + + {tab.props.children.type === CodeBlock + ? React.cloneElement(tab, { + children: React.cloneElement(tab.props.children, { + showHeader: false, + }), + }) + : tab} + + ))} +
+
+ ); +}; + +export default TabbedUseCaseCodeBlock; diff --git a/docs/docs.trychroma.com/components/markdoc/table.tsx b/docs/docs.trychroma.com/components/markdoc/table.tsx new file mode 100644 index 00000000000..ddc5fa86370 --- /dev/null +++ b/docs/docs.trychroma.com/components/markdoc/table.tsx @@ -0,0 +1,59 @@ +import { + Table as UITable, + TableHeader as UITableHeader, + TableBody as UITableBody, + TableRow as UITableRow, + TableHead as UITableHead, + TableCell as UITableCell, +} from "@/components/ui/table"; +import React from "react"; + +export const Table = React.forwardRef< + HTMLTableElement, + React.HTMLAttributes +>(({ ...props }, ref) => { + return ( +
+ +
+ ); +}); +Table.displayName = "Table"; + +export const TableHeader = React.forwardRef< + HTMLTableSectionElement, + React.HTMLAttributes +>(({ ...props }, ref) => ( + +)); +TableHeader.displayName = "TableHeader"; + +export const TableBody = React.forwardRef< + HTMLTableSectionElement, + React.HTMLAttributes +>(({ ...props }, ref) => ); +TableBody.displayName = "TableBody"; + +export const TableRow = React.forwardRef< + HTMLTableRowElement, + React.HTMLAttributes +>(({ ...props }, ref) => ); +TableRow.displayName = "TableRow"; + +export const TableHead = React.forwardRef< + HTMLTableCellElement, + React.ThHTMLAttributes +>(({ ...props }, ref) => ( + +)); +TableHead.displayName = "TableHead"; + +export const TableCell = React.forwardRef< + HTMLTableCellElement, + React.TdHTMLAttributes +>(({ ...props }, ref) => ); +TableCell.displayName = "TableCell"; diff --git a/docs/docs.trychroma.com/components/markdoc/tabs.tsx b/docs/docs.trychroma.com/components/markdoc/tabs.tsx new file mode 100644 index 00000000000..e6d1809ece8 --- /dev/null +++ b/docs/docs.trychroma.com/components/markdoc/tabs.tsx @@ -0,0 +1,92 @@ +"use client"; + +import React, { ReactElement, useContext, useRef } from "react"; +import { + Tabs as UITabs, + TabsContent, + TabsList, + TabsTrigger as UITabsTrigger, +} from "@/components/ui/tabs"; +import { capitalize, cn } from "@/lib/utils"; +import { tabLabelStyle } from "@/components/markdoc/code-block-header"; +import AppContext from "@/context/app-context"; +import CodeBlock from "@/components/markdoc/code-block"; +import { Playfair_Display } from "next/font/google"; + +export interface TabProps { + label: string; + children: React.ReactElement<{ content: string; showHeader: boolean }>; +} + +export const TabsTrigger = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ value, ...props }, ref) => { + const { setLanguage } = useContext(AppContext); + const triggerRef = useRef(null); + + return ( + { + setLanguage(value); + }} + /> + ); +}); +TabsTrigger.displayName = "TabsTrigger"; + +const Tab: React.FC = ({ children }) => { + return
{children}
; +}; + +export const Tabs: React.FC<{ children: ReactElement[] }> = ({ + children, +}) => { + const { language } = useContext(AppContext); + return ( +
+ + + {children.map((tab) => ( + + {capitalize(tab.props.label)} + + ))} + +
+ {children.map((tab) => ( + + {tab.props.children.type === CodeBlock + ? React.cloneElement(tab, { + children: React.cloneElement(tab.props.children, { + showHeader: false, + }), + }) + : tab} + + ))} +
+
+
+ ); +}; + +export default Tab; diff --git a/docs/docs.trychroma.com/components/posthog/posthog-pageview.tsx b/docs/docs.trychroma.com/components/posthog/posthog-pageview.tsx new file mode 100644 index 00000000000..fc7634d366b --- /dev/null +++ b/docs/docs.trychroma.com/components/posthog/posthog-pageview.tsx @@ -0,0 +1,34 @@ +"use client"; + +import { usePathname, useSearchParams } from "next/navigation"; +import React, { useEffect, Suspense } from "react"; +import { usePostHog } from "posthog-js/react"; + +export const PostHogPageView: React.FC = () => { + const pathname = usePathname(); + const searchParams = useSearchParams(); + const posthog = usePostHog(); + + useEffect(() => { + if (pathname && posthog) { + let url = window.origin + pathname; + if (searchParams.toString()) { + url = url + `?${searchParams.toString()}`; + } + + posthog.capture("$pageview", { $current_url: url }); + } + }, [pathname, searchParams, posthog]); + + return null; +}; + +const SuspendedPostHogPageView: React.FC = () => { + return ( + + + + ); +}; + +export default SuspendedPostHogPageView; diff --git a/docs/docs.trychroma.com/components/posthog/posthog-provider.tsx b/docs/docs.trychroma.com/components/posthog/posthog-provider.tsx new file mode 100644 index 00000000000..215e23bbdac --- /dev/null +++ b/docs/docs.trychroma.com/components/posthog/posthog-provider.tsx @@ -0,0 +1,27 @@ +"use client"; + +import posthog from "posthog-js"; +import { PostHogProvider as PHProvider } from "posthog-js/react"; +import React, { useEffect } from "react"; +import SuspendedPostHogPageView from "@/components/posthog/posthog-pageview"; + +const PostHogProvider: React.FC<{ children: React.ReactNode }> = ({ + children, +}) => { + useEffect(() => { + posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY!, { + api_host: process.env.NEXT_PUBLIC_POSTHOG_HOST, + person_profiles: "identified_only", + capture_pageview: false, + }); + }, []); + + return ( + + + {children} + + ); +}; + +export default PostHogProvider; diff --git a/docs/docs.trychroma.com/components/sidebar/cloud-icon.tsx b/docs/docs.trychroma.com/components/sidebar/cloud-icon.tsx new file mode 100644 index 00000000000..8db6c25bb8d --- /dev/null +++ b/docs/docs.trychroma.com/components/sidebar/cloud-icon.tsx @@ -0,0 +1,30 @@ +import React, { + ForwardRefExoticComponent, + RefAttributes, + forwardRef, +} from "react"; + +const CloudIcon: ForwardRefExoticComponent< + React.SVGProps & RefAttributes +> = forwardRef>((props, ref) => { + return ( + + + + ); +}); + +export default CloudIcon; diff --git a/docs/docs.trychroma.com/components/sidebar/menu-item.tsx b/docs/docs.trychroma.com/components/sidebar/menu-item.tsx new file mode 100644 index 00000000000..57d0e2977c7 --- /dev/null +++ b/docs/docs.trychroma.com/components/sidebar/menu-item.tsx @@ -0,0 +1,47 @@ +import React from "react"; +import Link from "next/link"; +import { AppSection } from "@/lib/content"; + +const MenuItem: React.FC<{ section: AppSection; active: boolean }> = ({ + section, + active, +}) => { + const Icon = section.icon!; + + return ( + +
+
+ +
+
+

+ {section.name} +

+ {section.comingSoon && ( +
+ Coming Soon +
+ )} +
+
+ + ); +}; + +export default MenuItem; diff --git a/docs/docs.trychroma.com/components/sidebar/page-index.tsx b/docs/docs.trychroma.com/components/sidebar/page-index.tsx new file mode 100644 index 00000000000..9756d5490d2 --- /dev/null +++ b/docs/docs.trychroma.com/components/sidebar/page-index.tsx @@ -0,0 +1,42 @@ +import React, { Suspense } from "react"; +import { Playfair_Display } from "next/font/google"; +import PageLink from "@/components/sidebar/page-link"; + +const playfairDisplay = Playfair_Display({ + subsets: ["latin"], + display: "swap", + weight: "500", + variable: "--font-playfair-display", +}); + +const PageIndex: React.FC<{ + path: string; + pages: { id: string; name: string }[]; + name?: string; +}> = ({ path, pages, name }) => { + return ( +
+ {name && ( +

+ {name} +

+ )} +
+ {pages.map((page) => ( + + + + ))} +
+
+ ); +}; + +export default PageIndex; diff --git a/docs/docs.trychroma.com/components/sidebar/page-link.tsx b/docs/docs.trychroma.com/components/sidebar/page-link.tsx new file mode 100644 index 00000000000..26e23fdde7a --- /dev/null +++ b/docs/docs.trychroma.com/components/sidebar/page-link.tsx @@ -0,0 +1,30 @@ +"use client"; + +import React from "react"; +import Link from "next/link"; +import { usePathname, useSearchParams } from "next/navigation"; + +const PageLink: React.FC<{ + id: string; + name: string; + path: string; + sectionPage: boolean; +}> = ({ id, name, path, sectionPage = true }) => { + const pathName = usePathname(); + const searchParams = useSearchParams(); + const active = pathName === path; + const lang = searchParams.get("lang"); + + return ( +
+ +

{name}

+ +
+ ); +}; + +export default PageLink; diff --git a/docs/docs.trychroma.com/components/sidebar/scrollable-content.tsx b/docs/docs.trychroma.com/components/sidebar/scrollable-content.tsx new file mode 100644 index 00000000000..c556f97de9a --- /dev/null +++ b/docs/docs.trychroma.com/components/sidebar/scrollable-content.tsx @@ -0,0 +1,69 @@ +"use client"; + +import React, { useEffect, useRef } from "react"; +import { usePathname } from "next/navigation"; + +const ScrollableContent: React.FC<{ + pagesIndex: string[]; + children: React.ReactNode; +}> = ({ pagesIndex, children }) => { + const pathname = usePathname(); + const scrollRef = useRef(null); + + const handleScroll = () => { + if (scrollRef.current) { + sessionStorage.setItem( + "sidebarScrollPosition", + scrollRef.current.scrollTop.toString(), + ); + } + }; + + useEffect(() => { + const sectionScrollPosition = (userPath: string[]) => { + const userPage = userPath[userPath.length - 1]; + const currentPage = pagesIndex.find((p) => p === userPage); + if (!currentPage) return 0; + return pagesIndex.indexOf(currentPage) * 25; + }; + + if (!scrollRef.current) return; + + const userPath = pathname.slice(1).split("/"); + const section = userPath[0]; + + const storedScrollPosition = sessionStorage.getItem( + "sidebarScrollPosition", + ); + + const storedSection = sessionStorage.getItem("sidebarSection"); + + if (!storedSection) { + sessionStorage.setItem("sidebarSection", section); + } else if (storedSection !== section) { + sessionStorage.setItem("sidebarSection", section); + sessionStorage.removeItem("sidebarScrollPosition"); + } + + if (storedScrollPosition) { + scrollRef.current.scrollTop = parseInt(storedScrollPosition, 10); + } else { + scrollRef.current.scrollTop = sectionScrollPosition(userPath); + } + + const ref = scrollRef.current; + ref.addEventListener("scroll", handleScroll); + return () => ref.removeEventListener("scroll", handleScroll); + }, [pathname, pagesIndex]); + + return ( +
+
{children}
+
+ ); +}; + +export default ScrollableContent; diff --git a/docs/docs.trychroma.com/components/sidebar/sidebar.tsx b/docs/docs.trychroma.com/components/sidebar/sidebar.tsx new file mode 100644 index 00000000000..2dea9c0274f --- /dev/null +++ b/docs/docs.trychroma.com/components/sidebar/sidebar.tsx @@ -0,0 +1,91 @@ +import React from "react"; +import MenuItem from "@/components/sidebar/menu-item"; +import sidebarConfig from "@/markdoc/content/sidebar-config"; +import PageIndex from "@/components/sidebar/page-index"; +import path from "path"; +import fs from "fs"; +import matter from "gray-matter"; +import ScrollableContent from "./scrollable-content"; + +const generatePages = (slug: string[]): { id: string; name: string }[] => { + const dirPath = path.join(process.cwd(), "markdoc", "content", ...slug); + const files = fs.readdirSync(dirPath); + + const pages = []; + + for (const file of files) { + if (file.endsWith(".md")) { + const filePath = path.join(dirPath, file); + const content = fs.readFileSync(filePath, "utf-8"); + + const { data } = matter(content); + if (data.id && data.name) { + pages.push({ id: data.id, name: data.name }); + } + } + } + + return pages; +}; + +const Sidebar: React.FC<{ path: string[]; mobile?: boolean }> = ({ + path, + mobile, +}) => { + const currentSection = sidebarConfig.find((section) => + path.join("").startsWith(section.id), + ); + + if (!currentSection) { + return null; + } + + const allSectionPages: string[] = [ + ...(currentSection.pages || []).map((p) => p.id), + ]; + currentSection.subsections?.forEach((subsection) => { + allSectionPages.push(...(subsection.pages?.map((p) => p.id) || [])); + }); + + return ( +
+
+
+ {sidebarConfig.map((section) => ( + + ))} +
+ + {currentSection.pages && ( +
+ +
+ )} + {currentSection.subsections?.map((subsection) => ( + + ))} +
+
+
+ ); +}; + +export default Sidebar; diff --git a/docs/docs.trychroma.com/components/ui/badge.tsx b/docs/docs.trychroma.com/components/ui/badge.tsx new file mode 100644 index 00000000000..120c5b50248 --- /dev/null +++ b/docs/docs.trychroma.com/components/ui/badge.tsx @@ -0,0 +1,36 @@ +import * as React from "react" +import { cva, type VariantProps } from "class-variance-authority" + +import { cn } from "@/lib/utils" + +const badgeVariants = cva( + "inline-flex items-center rounded-md border border-zinc-200 px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-zinc-950 focus:ring-offset-2 dark:border-zinc-800 dark:focus:ring-zinc-300", + { + variants: { + variant: { + default: + "border-transparent bg-zinc-900 text-zinc-50 shadow hover:bg-zinc-900/80 dark:bg-zinc-50 dark:text-zinc-900 dark:hover:bg-zinc-50/80", + secondary: + "border-transparent bg-zinc-100 text-zinc-900 hover:bg-zinc-100/80 dark:bg-zinc-800 dark:text-zinc-50 dark:hover:bg-zinc-800/80", + destructive: + "border-transparent bg-red-500 text-zinc-50 shadow hover:bg-red-500/80 dark:bg-red-900 dark:text-zinc-50 dark:hover:bg-red-900/80", + outline: "text-zinc-950 dark:text-zinc-50", + }, + }, + defaultVariants: { + variant: "default", + }, + } +) + +export interface BadgeProps + extends React.HTMLAttributes, + VariantProps {} + +function Badge({ className, variant, ...props }: BadgeProps) { + return ( +
+ ) +} + +export { Badge, badgeVariants } diff --git a/docs/docs.trychroma.com/components/ui/button.tsx b/docs/docs.trychroma.com/components/ui/button.tsx index 9edf7584bec..763a3e71164 100644 --- a/docs/docs.trychroma.com/components/ui/button.tsx +++ b/docs/docs.trychroma.com/components/ui/button.tsx @@ -1,24 +1,25 @@ -import * as React from "react" -import { Slot } from "@radix-ui/react-slot" -import { cva, type VariantProps } from "class-variance-authority" +import * as React from "react"; +import { Slot } from "@radix-ui/react-slot"; +import { cva, type VariantProps } from "class-variance-authority"; -import { cn } from "../../lib/utils" +import { cn } from "@/lib/utils"; const buttonVariants = cva( - "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50", + "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors disabled:pointer-events-none disabled:opacity-50", { variants: { variant: { default: - "bg-primary text-primary-foreground shadow hover:bg-primary/90", + "bg-zinc-900 text-zinc-50 shadow hover:bg-zinc-900/90 dark:bg-zinc-50 dark:text-zinc-900 dark:hover:bg-zinc-50/90", destructive: - "bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90", + "bg-red-500 text-zinc-50 shadow-sm hover:bg-red-500/90 dark:bg-red-900 dark:text-zinc-50 dark:hover:bg-red-900/90", outline: - "border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground", + "border border-zinc-200 bg-white shadow-sm hover:bg-zinc-100 hover:text-zinc-900 dark:border-zinc-800 dark:bg-zinc-950 dark:hover:bg-zinc-800 dark:hover:text-zinc-50", secondary: - "bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80", - ghost: "hover:bg-accent hover:text-accent-foreground", - link: "text-primary underline-offset-4 hover:underline", + "bg-zinc-100 text-zinc-900 shadow-sm hover:bg-zinc-100/80 dark:bg-zinc-800 dark:text-zinc-50 dark:hover:bg-zinc-800/80", + ghost: + "hover:bg-zinc-100 hover:text-zinc-900 dark:hover:bg-zinc-800 dark:hover:text-zinc-50", + link: "text-zinc-900 underline-offset-4 hover:underline dark:text-zinc-50", }, size: { default: "h-9 px-4 py-2", @@ -31,27 +32,27 @@ const buttonVariants = cva( variant: "default", size: "default", }, - } -) + }, +); export interface ButtonProps extends React.ButtonHTMLAttributes, VariantProps { - asChild?: boolean + asChild?: boolean; } const Button = React.forwardRef( ({ className, variant, size, asChild = false, ...props }, ref) => { - const Comp = asChild ? Slot : "button" + const Comp = asChild ? Slot : "button"; return ( - ) - } -) -Button.displayName = "Button" + ); + }, +); +Button.displayName = "Button"; -export { Button, buttonVariants } +export { Button, buttonVariants }; diff --git a/docs/docs.trychroma.com/components/ui/drawer.tsx b/docs/docs.trychroma.com/components/ui/drawer.tsx new file mode 100644 index 00000000000..547e4ac1427 --- /dev/null +++ b/docs/docs.trychroma.com/components/ui/drawer.tsx @@ -0,0 +1,118 @@ +"use client" + +import * as React from "react" +import { Drawer as DrawerPrimitive } from "vaul" + +import { cn } from "@/lib/utils" + +const Drawer = ({ + shouldScaleBackground = true, + ...props +}: React.ComponentProps) => ( + +) +Drawer.displayName = "Drawer" + +const DrawerTrigger = DrawerPrimitive.Trigger + +const DrawerPortal = DrawerPrimitive.Portal + +const DrawerClose = DrawerPrimitive.Close + +const DrawerOverlay = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +DrawerOverlay.displayName = DrawerPrimitive.Overlay.displayName + +const DrawerContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + + + +
+ {children} + + +)) +DrawerContent.displayName = "DrawerContent" + +const DrawerHeader = ({ + className, + ...props +}: React.HTMLAttributes) => ( +
+) +DrawerHeader.displayName = "DrawerHeader" + +const DrawerFooter = ({ + className, + ...props +}: React.HTMLAttributes) => ( +
+) +DrawerFooter.displayName = "DrawerFooter" + +const DrawerTitle = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +DrawerTitle.displayName = DrawerPrimitive.Title.displayName + +const DrawerDescription = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +DrawerDescription.displayName = DrawerPrimitive.Description.displayName + +export { + Drawer, + DrawerPortal, + DrawerOverlay, + DrawerTrigger, + DrawerClose, + DrawerContent, + DrawerHeader, + DrawerFooter, + DrawerTitle, + DrawerDescription, +} diff --git a/docs/docs.trychroma.com/components/ui/dropdown-menu.tsx b/docs/docs.trychroma.com/components/ui/dropdown-menu.tsx index 6d2e5f42de2..5f8a8549b25 100644 --- a/docs/docs.trychroma.com/components/ui/dropdown-menu.tsx +++ b/docs/docs.trychroma.com/components/ui/dropdown-menu.tsx @@ -1,3 +1,5 @@ +"use client" + import * as React from "react" import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu" import { @@ -6,7 +8,7 @@ import { DotFilledIcon, } from "@radix-ui/react-icons" -import { cn } from "../../lib/utils" +import { cn } from "@/lib/utils" const DropdownMenu = DropdownMenuPrimitive.Root @@ -29,7 +31,7 @@ const DropdownMenuSubTrigger = React.forwardRef< (({ className, ...props }, ref) => ( )) diff --git a/docs/docs.trychroma.com/components/ui/table.tsx b/docs/docs.trychroma.com/components/ui/table.tsx new file mode 100644 index 00000000000..db149d84966 --- /dev/null +++ b/docs/docs.trychroma.com/components/ui/table.tsx @@ -0,0 +1,120 @@ +import * as React from "react"; + +import { cn } from "@/lib/utils"; + +const Table = React.forwardRef< + HTMLTableElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+ + +)); +Table.displayName = "Table"; + +const TableHeader = React.forwardRef< + HTMLTableSectionElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( + +)); +TableHeader.displayName = "TableHeader"; + +const TableBody = React.forwardRef< + HTMLTableSectionElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( + +)); +TableBody.displayName = "TableBody"; + +const TableFooter = React.forwardRef< + HTMLTableSectionElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( + tr]:last:border-b-0 dark:bg-zinc-800/50", + className, + )} + {...props} + /> +)); +TableFooter.displayName = "TableFooter"; + +const TableRow = React.forwardRef< + HTMLTableRowElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( + +)); +TableRow.displayName = "TableRow"; + +const TableHead = React.forwardRef< + HTMLTableCellElement, + React.ThHTMLAttributes +>(({ className, ...props }, ref) => ( +
[role=checkbox]]:translate-y-[2px] dark:text-zinc-400", + className, + )} + {...props} + /> +)); +TableHead.displayName = "TableHead"; + +const TableCell = React.forwardRef< + HTMLTableCellElement, + React.TdHTMLAttributes +>(({ className, ...props }, ref) => ( + [role=checkbox]]:translate-y-[2px]", + className, + )} + {...props} + /> +)); +TableCell.displayName = "TableCell"; + +const TableCaption = React.forwardRef< + HTMLTableCaptionElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)); +TableCaption.displayName = "TableCaption"; + +export { + Table, + TableHeader, + TableBody, + TableFooter, + TableHead, + TableRow, + TableCell, + TableCaption, +}; diff --git a/docs/docs.trychroma.com/components/ui/tabs.tsx b/docs/docs.trychroma.com/components/ui/tabs.tsx index cf2e2ecf2f1..81b23d92b71 100644 --- a/docs/docs.trychroma.com/components/ui/tabs.tsx +++ b/docs/docs.trychroma.com/components/ui/tabs.tsx @@ -1,9 +1,9 @@ -import * as React from "react" -import * as TabsPrimitive from "@radix-ui/react-tabs" +import * as React from "react"; +import * as TabsPrimitive from "@radix-ui/react-tabs"; -import { cn } from "../../lib/utils" +import { cn } from "@/lib/utils"; -const Tabs = TabsPrimitive.Root +const Tabs = TabsPrimitive.Root; const TabsList = React.forwardRef< React.ElementRef, @@ -12,13 +12,13 @@ const TabsList = React.forwardRef< -)) -TabsList.displayName = TabsPrimitive.List.displayName +)); +TabsList.displayName = TabsPrimitive.List.displayName; const TabsTrigger = React.forwardRef< React.ElementRef, @@ -27,13 +27,13 @@ const TabsTrigger = React.forwardRef< -)) -TabsTrigger.displayName = TabsPrimitive.Trigger.displayName +)); +TabsTrigger.displayName = TabsPrimitive.Trigger.displayName; const TabsContent = React.forwardRef< React.ElementRef, @@ -42,12 +42,12 @@ const TabsContent = React.forwardRef< -)) -TabsContent.displayName = TabsPrimitive.Content.displayName +)); +TabsContent.displayName = TabsPrimitive.Content.displayName; -export { Tabs, TabsList, TabsTrigger, TabsContent } +export { Tabs, TabsList, TabsTrigger, TabsContent }; diff --git a/docs/docs.trychroma.com/components/ui/theme-provider.tsx b/docs/docs.trychroma.com/components/ui/theme-provider.tsx new file mode 100644 index 00000000000..7384b25e967 --- /dev/null +++ b/docs/docs.trychroma.com/components/ui/theme-provider.tsx @@ -0,0 +1,11 @@ +"use client"; + +import * as React from "react"; +import { ThemeProvider as NextThemesProvider } from "next-themes"; +import { type ThemeProviderProps } from "next-themes/dist/types"; + +const ThemeProvider = ({ children, ...props }: ThemeProviderProps) => { + return {children}; +}; + +export default ThemeProvider; diff --git a/docs/docs.trychroma.com/components/ui/toast.tsx b/docs/docs.trychroma.com/components/ui/toast.tsx deleted file mode 100644 index 673bb64d257..00000000000 --- a/docs/docs.trychroma.com/components/ui/toast.tsx +++ /dev/null @@ -1,127 +0,0 @@ -import * as React from "react" -import { Cross2Icon } from "@radix-ui/react-icons" -import * as ToastPrimitives from "@radix-ui/react-toast" -import { cva, type VariantProps } from "class-variance-authority" - -import { cn } from "../../lib/utils" - -const ToastProvider = ToastPrimitives.Provider - -const ToastViewport = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)) -ToastViewport.displayName = ToastPrimitives.Viewport.displayName - -const toastVariants = cva( - "group pointer-events-auto relative flex w-full items-center justify-between space-x-2 overflow-hidden rounded-md border p-4 pr-6 shadow-lg transition-all data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-[var(--radix-toast-swipe-end-x)] data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)] data-[swipe=move]:transition-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[swipe=end]:animate-out data-[state=closed]:fade-out-80 data-[state=closed]:slide-out-to-right-full data-[state=open]:slide-in-from-top-full data-[state=open]:sm:slide-in-from-bottom-full", - { - variants: { - variant: { - default: "border bg-background text-foreground", - destructive: - "destructive group border-destructive bg-destructive text-destructive-foreground", - }, - }, - defaultVariants: { - variant: "default", - }, - } -) - -const Toast = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef & - VariantProps ->(({ className, variant, ...props }, ref) => { - return ( - - ) -}) -Toast.displayName = ToastPrimitives.Root.displayName - -const ToastAction = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)) -ToastAction.displayName = ToastPrimitives.Action.displayName - -const ToastClose = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - - - -)) -ToastClose.displayName = ToastPrimitives.Close.displayName - -const ToastTitle = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)) -ToastTitle.displayName = ToastPrimitives.Title.displayName - -const ToastDescription = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)) -ToastDescription.displayName = ToastPrimitives.Description.displayName - -type ToastProps = React.ComponentPropsWithoutRef - -type ToastActionElement = React.ReactElement - -export { - type ToastProps, - type ToastActionElement, - ToastProvider, - ToastViewport, - Toast, - ToastTitle, - ToastDescription, - ToastClose, - ToastAction, -} diff --git a/docs/docs.trychroma.com/components/ui/toaster.tsx b/docs/docs.trychroma.com/components/ui/toaster.tsx deleted file mode 100644 index 88627292b4a..00000000000 --- a/docs/docs.trychroma.com/components/ui/toaster.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import { - Toast, - ToastClose, - ToastDescription, - ToastProvider, - ToastTitle, - ToastViewport, -} from "./toast" -import { useToast } from "./use-toast" - -export function Toaster() { - const { toasts } = useToast() - - return ( - - {toasts.map(function ({ id, title, description, action, ...props }) { - return ( - -
- {title && {title}} - {description && ( - {description} - )} -
- {action} - -
- ) - })} - -
- ) -} diff --git a/docs/docs.trychroma.com/components/ui/tooltip.tsx b/docs/docs.trychroma.com/components/ui/tooltip.tsx index 4bc5e2f0cd2..ab18090b8a4 100644 --- a/docs/docs.trychroma.com/components/ui/tooltip.tsx +++ b/docs/docs.trychroma.com/components/ui/tooltip.tsx @@ -1,7 +1,9 @@ +"use client" + import * as React from "react" import * as TooltipPrimitive from "@radix-ui/react-tooltip" -import { cn } from "../../lib/utils" +import { cn } from "@/lib/utils" const TooltipProvider = TooltipPrimitive.Provider @@ -13,15 +15,17 @@ const TooltipContent = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, sideOffset = 4, ...props }, ref) => ( - + + + )) TooltipContent.displayName = TooltipPrimitive.Content.displayName diff --git a/docs/docs.trychroma.com/components/ui/ui-button.tsx b/docs/docs.trychroma.com/components/ui/ui-button.tsx new file mode 100644 index 00000000000..118a7c05c91 --- /dev/null +++ b/docs/docs.trychroma.com/components/ui/ui-button.tsx @@ -0,0 +1,37 @@ +import React from "react"; +import { Button, buttonVariants } from "@/components/ui/button"; +import { cn } from "@/lib/utils"; +import { VariantProps } from "class-variance-authority"; + +interface UIButtonProps + extends React.ButtonHTMLAttributes, + VariantProps { + children?: React.ReactNode; + asChild?: boolean; +} + +const UIButton = React.forwardRef( + ({ children, className, variant, size, ...props }, ref) => { + const customStyles = cn( + "flex items-center justify-center border-x-[0.9px] border-y-[1px] shadow outline-none h-full rounded py-[0.2rem]", + "text-[#27201C] bg-gradient-to-b from-[#FFFFFF] to-[#f9f9f9] border-[#171716]/40 hover:bg-gradient-to-b hover:from-gray-100 hover:to-gray-100", + "dark:text-[#fff] dark:bg-gradient-to-b dark:from-[#171716] dark:to-[#171716] border-[0.8px] dark:border-[#fff]/40 dark:hover:from-[#171716]/90 dark:hover:to-[#171716]/90", + className, + ); + + return ( + + ); + }, +); +UIButton.displayName = "UIButton"; + +export default UIButton; diff --git a/docs/docs.trychroma.com/components/ui/use-toast.ts b/docs/docs.trychroma.com/components/ui/use-toast.ts deleted file mode 100644 index 36c572bcfb2..00000000000 --- a/docs/docs.trychroma.com/components/ui/use-toast.ts +++ /dev/null @@ -1,192 +0,0 @@ -// Inspired by react-hot-toast library -import * as React from "react" - -import type { - ToastActionElement, - ToastProps, -} from "./toast" - -const TOAST_LIMIT = 1 -const TOAST_REMOVE_DELAY = 1000000 - -type ToasterToast = ToastProps & { - id: string - title?: React.ReactNode - description?: React.ReactNode - action?: ToastActionElement -} - -const actionTypes = { - ADD_TOAST: "ADD_TOAST", - UPDATE_TOAST: "UPDATE_TOAST", - DISMISS_TOAST: "DISMISS_TOAST", - REMOVE_TOAST: "REMOVE_TOAST", -} as const - -let count = 0 - -function genId() { - count = (count + 1) % Number.MAX_SAFE_INTEGER - return count.toString() -} - -type ActionType = typeof actionTypes - -type Action = - | { - type: ActionType["ADD_TOAST"] - toast: ToasterToast - } - | { - type: ActionType["UPDATE_TOAST"] - toast: Partial - } - | { - type: ActionType["DISMISS_TOAST"] - toastId?: ToasterToast["id"] - } - | { - type: ActionType["REMOVE_TOAST"] - toastId?: ToasterToast["id"] - } - -interface State { - toasts: ToasterToast[] -} - -const toastTimeouts = new Map>() - -const addToRemoveQueue = (toastId: string) => { - if (toastTimeouts.has(toastId)) { - return - } - - const timeout = setTimeout(() => { - toastTimeouts.delete(toastId) - dispatch({ - type: "REMOVE_TOAST", - toastId: toastId, - }) - }, TOAST_REMOVE_DELAY) - - toastTimeouts.set(toastId, timeout) -} - -export const reducer = (state: State, action: Action): State => { - switch (action.type) { - case "ADD_TOAST": - return { - ...state, - toasts: [action.toast, ...state.toasts].slice(0, TOAST_LIMIT), - } - - case "UPDATE_TOAST": - return { - ...state, - toasts: state.toasts.map((t) => - t.id === action.toast.id ? { ...t, ...action.toast } : t - ), - } - - case "DISMISS_TOAST": { - const { toastId } = action - - // ! Side effects ! - This could be extracted into a dismissToast() action, - // but I'll keep it here for simplicity - if (toastId) { - addToRemoveQueue(toastId) - } else { - state.toasts.forEach((toast) => { - addToRemoveQueue(toast.id) - }) - } - - return { - ...state, - toasts: state.toasts.map((t) => - t.id === toastId || toastId === undefined - ? { - ...t, - open: false, - } - : t - ), - } - } - case "REMOVE_TOAST": - if (action.toastId === undefined) { - return { - ...state, - toasts: [], - } - } - return { - ...state, - toasts: state.toasts.filter((t) => t.id !== action.toastId), - } - } -} - -const listeners: Array<(state: State) => void> = [] - -let memoryState: State = { toasts: [] } - -function dispatch(action: Action) { - memoryState = reducer(memoryState, action) - listeners.forEach((listener) => { - listener(memoryState) - }) -} - -type Toast = Omit - -function toast({ ...props }: Toast) { - const id = genId() - - const update = (props: ToasterToast) => - dispatch({ - type: "UPDATE_TOAST", - toast: { ...props, id }, - }) - const dismiss = () => dispatch({ type: "DISMISS_TOAST", toastId: id }) - - dispatch({ - type: "ADD_TOAST", - toast: { - ...props, - id, - open: true, - onOpenChange: (open) => { - if (!open) dismiss() - }, - }, - }) - - return { - id: id, - dismiss, - update, - } -} - -function useToast() { - const [state, setState] = React.useState(memoryState) - - React.useEffect(() => { - listeners.push(setState) - return () => { - const index = listeners.indexOf(setState) - if (index > -1) { - listeners.splice(index, 1) - } - } - }, [state]) - - return { - ...state, - toast, - dismiss: (toastId?: string) => dispatch({ type: "DISMISS_TOAST", toastId }), - } -} - -export { useToast, toast } diff --git a/docs/docs.trychroma.com/context/app-context.tsx b/docs/docs.trychroma.com/context/app-context.tsx new file mode 100644 index 00000000000..af5b9b9be91 --- /dev/null +++ b/docs/docs.trychroma.com/context/app-context.tsx @@ -0,0 +1,45 @@ +import React, { + createContext, + useState, + ReactNode, + useContext, + useEffect, +} from "react"; +import { usePathname, useRouter, useSearchParams } from "next/navigation"; + +export interface AppContextValue { + language: string; + setLanguage: (language: string) => void; +} + +const AppContextDefaultValue: AppContextValue = { + language: "python", + setLanguage: () => {}, +}; + +const AppContext = createContext(AppContextDefaultValue); + +export const AppContextProvider = ({ children }: { children: ReactNode }) => { + const searchParams = useSearchParams(); + const [language, setLanguage] = useState( + searchParams.get("lang") || "python", + ); + const router = useRouter(); + const pathname = usePathname(); + + useEffect(() => { + if (language === "typescript") { + router.replace(`${pathname}?lang=typescript`); + } else { + router.replace(pathname); + } + }, [language]); + + return ( + + {children} + + ); +}; + +export default AppContext; diff --git a/docs/docs.trychroma.com/lib/content.ts b/docs/docs.trychroma.com/lib/content.ts new file mode 100644 index 00000000000..85e71c760c7 --- /dev/null +++ b/docs/docs.trychroma.com/lib/content.ts @@ -0,0 +1,76 @@ +import { ForwardRefExoticComponent, RefAttributes } from "react"; + +export interface AppPage { + id: string; + name: string; + slug?: string; + path?: string; +} + +export interface AppSection { + id: string; + name: string; + default?: string; + icon?: ForwardRefExoticComponent< + { className?: string } & RefAttributes + >; + pages?: AppPage[]; + generatePages?: boolean; + subsections?: AppSection[]; + comingSoon?: boolean; + override?: string; +} + +export const getAllPages = (sidebarConfig: AppSection[], sectionId: string) => { + const section = sidebarConfig.find((section) => section.id === sectionId); + if (!section) { + return []; + } + + const pages: { id: string; name: string; slug: string }[] = []; + + pages.push( + ...(section.pages?.map((page) => { + return { + ...page, + slug: `${section.id}/${page.id}`, + path: `./${page.slug}`, + }; + }) || []), + ); + + section.subsections?.forEach((subsection) => { + pages.push( + ...(subsection.pages?.map((page) => { + return { + ...page, + slug: `${section.id}/${subsection.id}/${page.id}`, + path: `../${subsection.id}/${page.id}`, + }; + }) || []), + ); + }); + + return pages; +}; + +export const getPagePrevNext = ( + slug: string[], + pages: AppPage[], +): { + prev?: AppPage; + next?: AppPage; +} => { + const page = slug.join("/"); + const pageIndex = pages.map((page) => page.slug).indexOf(page); + if (pageIndex === -1) { + return { prev: undefined, next: undefined }; + } + if (pageIndex === pages.length - 1) { + return { prev: pages[pageIndex - 1], next: undefined }; + } + if (pageIndex === 0) { + return { prev: undefined, next: pages[pageIndex + 1] }; + } + return { prev: pages[pageIndex - 1], next: pages[pageIndex + 1] }; +}; diff --git a/docs/docs.trychroma.com/lib/utils.ts b/docs/docs.trychroma.com/lib/utils.ts index d084ccade0d..5ef0403a1f9 100644 --- a/docs/docs.trychroma.com/lib/utils.ts +++ b/docs/docs.trychroma.com/lib/utils.ts @@ -1,6 +1,14 @@ -import { type ClassValue, clsx } from "clsx" -import { twMerge } from "tailwind-merge" +import { type ClassValue, clsx } from "clsx"; +import { twMerge } from "tailwind-merge"; -export function cn(...inputs: ClassValue[]) { - return twMerge(clsx(inputs)) -} +export const cn = (...inputs: ClassValue[]) => { + return twMerge(clsx(inputs)); +}; + +export const formatToK = (num: number) => { + return `${Math.round(num / 1000)}k`; +}; + +export const capitalize = (str: string) => { + return `${str.charAt(0).toUpperCase()}${str.slice(1)}`; +}; diff --git a/docs/docs.trychroma.com/markdoc/config.ts b/docs/docs.trychroma.com/markdoc/config.ts new file mode 100644 index 00000000000..7eddc716ad8 --- /dev/null +++ b/docs/docs.trychroma.com/markdoc/config.ts @@ -0,0 +1,134 @@ +import type { Config } from "@markdoc/markdoc"; +import React from "react"; +import InlineCode from "@/components/markdoc/inline-code"; +import CodeBlock from "@/components/markdoc/code-block"; +import TabbedUseCaseCodeBlock from "@/components/markdoc/tabbed-use-case-code-block"; +import Tab, { Tabs } from "@/components/markdoc/tabs"; +import { + Table, + TableHeader, + TableBody, + TableRow, + TableHead, + TableCell, +} from "@/components/markdoc/table"; +import TabbedCodeBlock from "@/components/markdoc/tabbed-code-block"; +import CenteredContent from "@/components/markdoc/centered-content"; +import Latex from "@/components/markdoc/latex"; +import Banner from "@/components/markdoc/banner"; +import Heading from "@/components/markdoc/markdoc-heading"; + +interface MarkDocConfig extends Config { + components?: Record>; +} + +const markdocConfig: MarkDocConfig = { + nodes: { + code: { + render: "InlineCode", + attributes: { + content: { type: String }, + }, + }, + fence: { + render: "CodeBlock", + attributes: { + content: { type: String }, + language: { type: String }, + }, + }, + table: { + render: "Table", + }, + thead: { + render: "TableHeader", + }, + tbody: { + render: "TableBody", + }, + tr: { + render: "TableRow", + }, + th: { + render: "TableHead", + }, + td: { + render: "TableCell", + }, + heading: { + render: "Heading", + attributes: { + level: { type: "Number", required: true }, + id: { type: "String", required: false }, + }, + }, + }, + tags: { + TabbedCodeBlock: { + render: "TabbedCodeBlock", + selfClosing: true, + }, + TabbedUseCaseCodeBlock: { + render: "TabbedUseCaseCodeBlock", + selfClosing: false, + attributes: { + language: { + type: String, + required: true, + }, + }, + }, + Tab: { + render: "Tab", + selfClosing: false, + attributes: { + label: { + type: String, + required: true, + }, + }, + }, + Tabs: { + render: "Tabs", + selfClosing: false, + }, + CenteredContent: { + render: "CenteredContent", + selfClosing: false, + }, + Banner: { + render: "Banner", + attributes: { + type: { + type: String, + required: true, + }, + }, + selfClosing: false, + }, + Latex: { + render: "Latex", + selfClosing: false, + }, + }, + components: { + InlineCode, + CodeBlock, + TabbedCodeBlock, + TabbedUseCaseCodeBlock, + Tab, + Tabs: Tabs, + Table, + TableHeader, + TableBody, + TableRow, + TableHead, + TableCell, + CenteredContent, + Banner, + Latex, + Heading, + }, +}; + +export default markdocConfig; diff --git a/docs/docs.trychroma.com/markdoc/content/cli/install-and-run.md b/docs/docs.trychroma.com/markdoc/content/cli/install-and-run.md new file mode 100644 index 00000000000..40def5552b5 --- /dev/null +++ b/docs/docs.trychroma.com/markdoc/content/cli/install-and-run.md @@ -0,0 +1,38 @@ +# Install and Run + +You can install the Chroma CLI with `pip`: + +```terminal +pip install chromadb +``` + +You can then run a Chroma server locally with the `chroma run` command: + +```terminal +chroma run --path [/path/to/persist/data] +``` + +Your Chroma server will persist its data in the path you provide after the `path` argument. By default, +it will save data to the `.chroma` directory. + +With your Chroma server running, you can connect to it with the `HttpClient`: + +{% TabbedCodeBlock %} + +{% Tab label="python" %} +```python +import chromadb + +chroma_client = chromadb.HttpClient(host='localhost', port=8000) +``` +{% /Tab %} + +{% Tab label="typescript" %} +```typescript +import { ChromaClient } from "chromadb"; + +const client = new ChromaClient(); +``` +{% /Tab %} + +{% /TabbedCodeBlock %} diff --git a/docs/docs.trychroma.com/pages/reference/cli.md b/docs/docs.trychroma.com/markdoc/content/cli/vacuum.md similarity index 86% rename from docs/docs.trychroma.com/pages/reference/cli.md rename to docs/docs.trychroma.com/markdoc/content/cli/vacuum.md index a9390b86405..42459263e2a 100644 --- a/docs/docs.trychroma.com/pages/reference/cli.md +++ b/docs/docs.trychroma.com/markdoc/content/cli/vacuum.md @@ -1,8 +1,4 @@ ---- -title: CLI ---- - -## Vacuuming +# Vacuuming Vacuuming shrinks and optimizes your database. @@ -18,4 +14,4 @@ To vacuum your database, run: chroma utils vacuum --path ``` -For large databases, expect this to take up to a few minutes. +For large databases, expect this to take up to a few minutes. \ No newline at end of file diff --git a/docs/docs.trychroma.com/markdoc/content/docs/collections/add-data.md b/docs/docs.trychroma.com/markdoc/content/docs/collections/add-data.md new file mode 100644 index 00000000000..9c930275509 --- /dev/null +++ b/docs/docs.trychroma.com/markdoc/content/docs/collections/add-data.md @@ -0,0 +1,89 @@ +# Adding Data to Chroma Collections + +Add data to Chroma with `.add`. + +Raw documents: + +{% TabbedCodeBlock %} + +{% Tab label="python" %} +```python +collection.add( + documents=["lorem ipsum...", "doc2", "doc3", ...], + metadatas=[{"chapter": "3", "verse": "16"}, {"chapter": "3", "verse": "5"}, {"chapter": "29", "verse": "11"}, ...], + ids=["id1", "id2", "id3", ...] +) +``` +{% /Tab %} + +{% Tab label="typescript" %} +```typescript +await collection.add({ + ids: ["id1", "id2", "id3", ...], + metadatas: [{"chapter": "3", "verse": "16"}, {"chapter": "3", "verse": "5"}, {"chapter": "29", "verse": "11"}, ...], + documents: ["lorem ipsum...", "doc2", "doc3", ...], +}); +``` +{% /Tab %} + +{% /TabbedCodeBlock %} + +If Chroma is passed a list of `documents`, it will automatically tokenize and embed them with the collection's embedding function (the default will be used if none was supplied at collection creation). Chroma will also store the `documents` themselves. If the documents are too large to embed using the chosen embedding function, an exception will be raised. + +Each document must have a unique associated `id`. Trying to `.add` the same ID twice will result in only the initial value being stored. An optional list of `metadata` dictionaries can be supplied for each document, to store additional information and enable filtering. + +Alternatively, you can supply a list of document-associated `embeddings` directly, and Chroma will store the associated documents without embedding them itself. + +{% TabbedCodeBlock %} + +{% Tab label="python" %} +```python +collection.add( + documents=["doc1", "doc2", "doc3", ...], + embeddings=[[1.1, 2.3, 3.2], [4.5, 6.9, 4.4], [1.1, 2.3, 3.2], ...], + metadatas=[{"chapter": "3", "verse": "16"}, {"chapter": "3", "verse": "5"}, {"chapter": "29", "verse": "11"}, ...], + ids=["id1", "id2", "id3", ...] +) +``` +{% /Tab %} + +{% Tab label="typescript" %} +```typescript +await collection.add({ + ids: ["id1", "id2", "id3", ...], + embeddings: [[1.1, 2.3, 3.2], [4.5, 6.9, 4.4], [1.1, 2.3, 3.2], ...], + metadatas: [{"chapter": "3", "verse": "16"}, {"chapter": "3", "verse": "5"}, {"chapter": "29", "verse": "11"}, ...], + documents: ["lorem ipsum...", "doc2", "doc3", ...], +}) +``` +{% /Tab %} + +{% /TabbedCodeBlock %} + +If the supplied `embeddings` are not the same dimension as the collection, an exception will be raised. + +You can also store documents elsewhere, and just supply a list of `embeddings` and `metadata` to Chroma. You can use the `ids` to associate the embeddings with your documents stored elsewhere. + +{% TabbedCodeBlock %} + +{% Tab label="python" %} +```python +collection.add( + embeddings=[[1.1, 2.3, 3.2], [4.5, 6.9, 4.4], [1.1, 2.3, 3.2], ...], + metadatas=[{"chapter": "3", "verse": "16"}, {"chapter": "3", "verse": "5"}, {"chapter": "29", "verse": "11"}, ...], + ids=["id1", "id2", "id3", ...] +) +``` +{% /Tab %} + +{% Tab label="typescript" %} +```typescript +await collection.add({ + ids: ["id1", "id2", "id3", ...], + embeddings: [[1.1, 2.3, 3.2], [4.5, 6.9, 4.4], [1.1, 2.3, 3.2], ...], + metadatas: [{"chapter": "3", "verse": "16"}, {"chapter": "3", "verse": "5"}, {"chapter": "29", "verse": "11"}, ...], +}) +``` +{% /Tab %} + +{% /TabbedCodeBlock %} diff --git a/docs/docs.trychroma.com/markdoc/content/docs/collections/configure.md b/docs/docs.trychroma.com/markdoc/content/docs/collections/configure.md new file mode 100644 index 00000000000..8bc7fbe85bc --- /dev/null +++ b/docs/docs.trychroma.com/markdoc/content/docs/collections/configure.md @@ -0,0 +1,50 @@ +# Configuring Chroma Collections + +You can configure the embedding space of a collection by setting special keys on a collection's metadata. These configurations will help you customize your Chroma collections for different data, accuracy and performance requirements. + +* `hnsw:space` defines the distance function of the embedding space. The default is `l2` (squared L2 norm), and other possible values are `cosine` (cosine similarity), and `ip` (inner product). + +| Distance | parameter | Equation | +| ----------------- | :-------: |-----------------------------------------------------------------------------------------------------------------------------------------------------------:| +| Squared L2 | `l2` | {% Latex %} d = \\sum\\left(A_i-B_i\\right)^2 {% /Latex %} | +| Inner product | `ip` | {% Latex %} d = 1.0 - \\sum\\left(A_i \\times B_i\\right) {% /Latex %} | +| Cosine similarity | `cosine` | {% Latex %} d = 1.0 - \\frac{\\sum\\left(A_i \\times B_i\\right)}{\\sqrt{\\sum\\left(A_i^2\\right)} \\cdot \\sqrt{\\sum\\left(B_i^2\\right)}} {% /Latex %} | + +* `hnsw:ef_construction` determines the size of the candidate list used to select neighbors during index creation. A higher value improves index quality at the cost of more memory and time, while a lower value speeds up construction with reduced accuracy. The default value is `100`. +* `hnsw:ef_search` determines the size of the dynamic candidate list used while searching for the nearest neighbors. A higher value improves recall and accuracy by exploring more potential neighbors but increases query time and computational cost, while a lower value results in faster but less accurate searches. The default value is `10`. +* `hnsw:M` is the maximum number of neighbors (connections) that each node in the graph can have during the construction of the index. A higher value results in a denser graph, leading to better recall and accuracy during searches but increases memory usage and construction time. A lower value creates a sparser graph, reducing memory usage and construction time but at the cost of lower search accuracy and recall. The default value is `16`. +* `hnsw:num_threads` specifies the number of threads to use during index construction or search operations. The default value is `multiprocessing.cpu_count()` (available CPU cores). + +Here is an example of how you can create a collection and configure it with custom HNSW settings: + +{% TabbedCodeBlock %} + +{% Tab label="python" %} +```python +collection = client.create_collection( + name="my_collection", + embedding_function=emb_fn, + metadata={ + "hnsw:space": "cosine", + "hnsw:ef_search": 100 + } +) +``` +{% /Tab %} + +{% Tab label="typescript" %} +```typescript +let collection = await client.createCollection({ + name: "my_collection", + embeddingFunction: emb_fn, + metadata: { + "hnsw:space": "cosine", + "hnsw:ef_search": 100 + } +}); +``` +{% /Tab %} + +{% /TabbedCodeBlock %} + +You can learn more in our [Embeddings section](../embeddings/embedding-functions). \ No newline at end of file diff --git a/docs/docs.trychroma.com/markdoc/content/docs/collections/create-get-delete.md b/docs/docs.trychroma.com/markdoc/content/docs/collections/create-get-delete.md new file mode 100644 index 00000000000..e626426ee8d --- /dev/null +++ b/docs/docs.trychroma.com/markdoc/content/docs/collections/create-get-delete.md @@ -0,0 +1,127 @@ +# Create, Get, and Delete Chroma Collections + +Chroma lets you manage collections of embeddings, using the `collection` primitive. + +Chroma uses collection names in the url, so there are a few restrictions on naming them: + +- The length of the name must be between 3 and 63 characters. +- The name must start and end with a lowercase letter or a digit, and it can contain dots, dashes, and underscores in between. +- The name must not contain two consecutive dots. +- The name must not be a valid IP address. + +Chroma collections are created with a name and an optional embedding function. + +{% Banner type="note" %} +If you supply an embedding function, you must supply it every time you get the collection. +{% /Banner %} + +{% TabbedCodeBlock %} + +{% Tab label="python" %} +```python +collection = client.create_collection(name="my_collection", embedding_function=emb_fn) +collection = client.get_collection(name="my_collection", embedding_function=emb_fn) +``` +{% /Tab %} + +{% Tab label="typescript" %} +```typescript +let collection = await client.createCollection({ + name: "my_collection", + embeddingFunction: emb_fn, +}); + +collection = await client.getCollection({ + name: "my_collection", + embeddingFunction: emb_fn, +}); +``` +{% /Tab %} + +{% /TabbedCodeBlock %} + +The embedding function takes text as input and embeds it. If no embedding function is supplied, Chroma will use [sentence transformer](https://www.sbert.net/index.html) as a default. You can learn more about [embedding functions](../embeddings/embedding-functions), and how to create your own. + +When creating collections, you can pass the optional `metadata` argument to add a mapping of metadata key-value pairs to your collections. This can be useful for adding general about the collection like creation time, description of the data stored in the collection, and more. + +{% TabbedCodeBlock %} + +{% Tab label="python" %} +```python +from datetime import datetime + +collection = client.create_collection( + name="my_collection", + embedding_function=emb_fn, + metadata={ + "description": "my first Chroma collection", + "created": str(datetime.now()) + } +) +``` +{% /Tab %} + +{% Tab label="typescript" %} +```typescript +let collection = await client.createCollection({ + name: "my_collection", + embeddingFunction: emb_fn, + metadata: { + description: "my first Chroma collection", + created: (new Date()).toString() + } +}); +``` +{% /Tab %} + +{% /TabbedCodeBlock %} + +The collection metadata is also used to configure the embedding space of a collection. Learn more about it in [Configuring Chroma Collections](./configure). + +The Chroma client allows you to get and delete existing collections by their name. It also offers a `get or create` method to get a collection if it exists, or create it otherwise. + +{% TabbedCodeBlock %} + +{% Tab label="python" %} +```python +collection = client.get_collection(name="test") # Get a collection object from an existing collection, by name. Will raise an exception if it's not found. +collection = client.get_or_create_collection(name="test") # Get a collection object from an existing collection, by name. If it doesn't exist, create it. +client.delete_collection(name="my_collection") # Delete a collection and all associated embeddings, documents, and metadata. ⚠️ This is destructive and not reversible +``` +{% /Tab %} + +{% Tab label="typescript" %} +```typescript +const collection = await client.getCollection({ name: "test" }); // Get a collection object from an existing collection, by name. Will raise an exception of it's not found. +collection = await client.getOrCreateCollection({ name: "test" }); // Get a collection object from an existing collection, by name. If it doesn't exist, create it. +await client.deleteCollection(collection); // Delete a collection and all associated embeddings, documents, and metadata. ⚠️ This is destructive and not reversible +``` +{% /Tab %} + +{% /TabbedCodeBlock %} + +Collections have a few useful convenience methods. + +* `peek()` - returns a list of the first 10 items in the collection. +* `count()` - returns the number of items in the collection. +* `modify()` - rename the collection + +{% TabbedCodeBlock %} + +{% Tab label="python" %} +```python +collection.peek() +collection.count() +collection.modify(name="new_name") +``` +{% /Tab %} + +{% Tab label="typescript" %} +```typescript +await collection.peek(); +await collection.count(); +await collection.modify({ name: "new_name" }) +``` +{% /Tab %} + +{% /TabbedCodeBlock %} \ No newline at end of file diff --git a/docs/docs.trychroma.com/markdoc/content/docs/collections/delete-data.md b/docs/docs.trychroma.com/markdoc/content/docs/collections/delete-data.md new file mode 100644 index 00000000000..3844fb59ebf --- /dev/null +++ b/docs/docs.trychroma.com/markdoc/content/docs/collections/delete-data.md @@ -0,0 +1,31 @@ +# Deleting Data from Chroma Collections + +Chroma supports deleting items from a collection by `id` using `.delete`. The embeddings, documents, and metadata associated with each item will be deleted. + +{% Banner type="warn" %} +Naturally, this is a destructive operation, and cannot be undone. +{% /Banner %} + +`.delete` also supports the `where` filter. If no `ids` are supplied, it will delete all items in the collection that match the `where` filter. + +{% TabbedCodeBlock %} + +{% Tab label="python" %} +```python +collection.delete( + ids=["id1", "id2", "id3",...], + where={"chapter": "20"} +) +``` +{% /Tab %} + +{% Tab label="typescript" %} +```typescript +await collection.delete({ + ids: ["id1", "id2", "id3",...], //ids + where: {"chapter": "20"} //where +}) +``` +{% /Tab %} + +{% /TabbedCodeBlock %} \ No newline at end of file diff --git a/docs/docs.trychroma.com/markdoc/content/docs/collections/update-data.md b/docs/docs.trychroma.com/markdoc/content/docs/collections/update-data.md new file mode 100644 index 00000000000..905851142a8 --- /dev/null +++ b/docs/docs.trychroma.com/markdoc/content/docs/collections/update-data.md @@ -0,0 +1,71 @@ +# Updating Data in Chroma Collections + +Any property of records in a collection can be updated with `.update`: + +{% TabbedCodeBlock %} + +{% Tab label="python" %} +```python +collection.update( + ids=["id1", "id2", "id3", ...], + embeddings=[[1.1, 2.3, 3.2], [4.5, 6.9, 4.4], [1.1, 2.3, 3.2], ...], + metadatas=[{"chapter": "3", "verse": "16"}, {"chapter": "3", "verse": "5"}, {"chapter": "29", "verse": "11"}, ...], + documents=["doc1", "doc2", "doc3", ...], +) +``` +{% /Tab %} + +{% Tab label="typescript" %} +```typescript +await collection.update({ + ids: ["id1", "id2", "id3", ...], + embeddings: [[1.1, 2.3, 3.2], [4.5, 6.9, 4.4], [1.1, 2.3, 3.2], ...], + metadatas: [{"chapter": "3", "verse": "16"}, {"chapter": "3", "verse": "5"}, {"chapter": "29", "verse": "11"}, ...], + documents: ["doc1", "doc2", "doc3", ...] +}) +``` +{% /Tab %} + +{% /TabbedCodeBlock %} + +If an `id` is not found in the collection, an error will be logged and the update will be ignored. If `documents` are supplied without corresponding `embeddings`, the embeddings will be recomputed with the collection's embedding function. + +If the supplied `embeddings` are not the same dimension as the collection, an exception will be raised. + +Chroma also supports an `upsert` operation, which updates existing items, or adds them if they don't yet exist. + +{% TabbedCodeBlock %} + +{% Tab label="python" %} +```python +collection.upsert( + ids=["id1", "id2", "id3", ...], + embeddings=[[1.1, 2.3, 3.2], [4.5, 6.9, 4.4], [1.1, 2.3, 3.2], ...], + metadatas=[{"chapter": "3", "verse": "16"}, {"chapter": "3", "verse": "5"}, {"chapter": "29", "verse": "11"}, ...], + documents=["doc1", "doc2", "doc3", ...], +) +``` +{% /Tab %} + +{% Tab label="typescript" %} +```typescript +await collection.upsert({ + ids: ["id1", "id2", "id3"], + embeddings: [ + [1.1, 2.3, 3.2], + [4.5, 6.9, 4.4], + [1.1, 2.3, 3.2], + ], + metadatas: [ + { chapter: "3", verse: "16" }, + { chapter: "3", verse: "5" }, + { chapter: "29", verse: "11" }, + ], + documents: ["doc1", "doc2", "doc3"], +}); +``` +{% /Tab %} + +{% /TabbedCodeBlock %} + +If an `id` is not present in the collection, the corresponding items will be created as per `add`. Items with existing `id`s will be updated as per `update`. \ No newline at end of file diff --git a/docs/docs.trychroma.com/markdoc/content/docs/embeddings/embedding-functions.md b/docs/docs.trychroma.com/markdoc/content/docs/embeddings/embedding-functions.md new file mode 100644 index 00000000000..7387f1f2556 --- /dev/null +++ b/docs/docs.trychroma.com/markdoc/content/docs/embeddings/embedding-functions.md @@ -0,0 +1,125 @@ +# Embedding Functions + +Embeddings are the way to represent any kind of data, making them the perfect fit for working with all kinds of A.I-powered tools and algorithms. They can represent text, images, and soon audio and video. There are many options for creating embeddings, whether locally using an installed library, or by calling an API. + +Chroma provides lightweight wrappers around popular embedding providers, making it easy to use them in your apps. You can set an embedding function when you create a Chroma collection, which will be used automatically, or you can call them directly yourself. + +| | Python | Typescript | +|------------------------------------------------------------------------------------------|--------|------------| +| [OpenAI](../../integrations/embedding-models/openai) | ✓ | ✓ | +| [Google Generative AI](../../integrations/embedding-models/google-gemini) | ✓ | ✓ | +| [Cohere](../../integrations/embedding-models/cohere) | ✓ | ✓ | +| [Hugging Face](../../integrations/embedding-models/hugging-face) | ✓ | - | +| [Instructor](../../integrations/embedding-models/instructor) | ✓ | - | +| [Hugging Face Embedding Server](../../integrations/embedding-models/hugging-face-server) | ✓ | ✓ | +| [Jina AI](../../integrations/embedding-models/jinaai) | ✓ | ✓ | + +We welcome pull requests to add new Embedding Functions to the community. + +*** + +## Default: all-MiniLM-L6-v2 + +By default, Chroma uses the [Sentence Transformers](https://www.sbert.net/) `all-MiniLM-L6-v2` model to create embeddings. This embedding model can create sentence and document embeddings that can be used for a wide variety of tasks. This embedding function runs locally on your machine, and may require you download the model files (this will happen automatically). + +{% TabbedCodeBlock %} + +{% Tab label="python" %} +```python +from chromadb.utils import embedding_functions +default_ef = embedding_functions.DefaultEmbeddingFunction() +``` +{% /Tab %} + +{% Tab label="typescript" %} +```typescript +import { DefaultEmbeddingFunction } from "chromadb"; +const defaultEF = new DefaultEmbeddingFunction(); +``` +{% /Tab %} + +{% /TabbedCodeBlock %} + +Embedding functions can be linked to a collection and used whenever you call `add`, `update`, `upsert` or `query`. You can also use them directly which can be handy for debugging. + +{% TabbedCodeBlock %} + +{% Tab label="python" %} +```python +val = default_ef(["foo"]) +print(val) # [[0.05035809800028801, 0.0626462921500206, -0.061827320605516434...]] +``` +{% /Tab %} + +{% Tab label="typescript" %} +```typescript +const val = defaultEf.generate(["foo"]); +console.log(val); // [[0.05035809800028801, 0.0626462921500206, -0.061827320605516434...]] +``` +{% /Tab %} + +{% /TabbedCodeBlock %} + +## Sentence Transformers + +Chroma can also use any [Sentence Transformers](https://www.sbert.net/) model to create embeddings. + +You can pass in an optional `model_name` argument, which lets you choose which Sentence Transformers model to use. By default, Chroma uses `all-MiniLM-L6-v2`. You can see a list of all available models [here](https://www.sbert.net/docs/pretrained_models.html). + +{% TabbedCodeBlock %} + +{% Tab label="python" %} +```python +sentence_transformer_ef = embedding_functions.SentenceTransformerEmbeddingFunction( + model_name="all-MiniLM-L6-v2" +) +``` +{% /Tab %} + +{% Tab label="typescript" %} +```typescript +import { DefaultEmbeddingFunction } from "chromadb"; +const modelName = "all-MiniLM-L6-v2"; +const defaultEF = new DefaultEmbeddingFunction(modelName); +``` +{% /Tab %} + +{% /TabbedCodeBlock %} + +## Custom Embedding Functions + +You can create your own embedding function to use with Chroma, it just needs to implement the `EmbeddingFunction` protocol. + +{% TabbedCodeBlock %} + +{% Tab label="python" %} +```python +from chromadb import Documents, EmbeddingFunction, Embeddings + +class MyEmbeddingFunction(EmbeddingFunction): + def __call__(self, input: Documents) -> Embeddings: + # embed the documents somehow + return embeddings +``` +{% /Tab %} + +{% Tab label="typescript" %} +```typescript +class MyEmbeddingFunction { + private api_key: string; + + constructor(api_key: string) { + this.api_key = api_key; + } + + public async generate(texts: string[]): Promise { + // do things to turn texts into embeddings with an api_key perhaps + return embeddings; + } +} +``` +{% /Tab %} + +{% /TabbedCodeBlock %} + +We welcome contributions! If you create an embedding function that you think would be useful to others, please consider [submitting a pull request](https://github.com/chroma-core/chroma) to add it to Chroma's `embedding_functions` module. diff --git a/docs/docs.trychroma.com/pages/guides/multimodal.md b/docs/docs.trychroma.com/markdoc/content/docs/embeddings/multimodal.md similarity index 85% rename from docs/docs.trychroma.com/pages/guides/multimodal.md rename to docs/docs.trychroma.com/markdoc/content/docs/embeddings/multimodal.md index 01a7ee6e565..1618e0aa04d 100644 --- a/docs/docs.trychroma.com/pages/guides/multimodal.md +++ b/docs/docs.trychroma.com/markdoc/content/docs/embeddings/multimodal.md @@ -1,25 +1,12 @@ ---- -title: "🖼️ Multimodal" ---- +# Multimodal -{% tabs group="code-lang" hideContent=true %} - -{% tab label="Python" %} -{% /tab %} - -{% tab label="Javascript" %} -{% /tab %} - -{% /tabs %} - ---- - -{% tabs group="code-lang" hideTabs=true %} -{% tab label="Python" %} +{% Banner type="note" %} +Multimodal support is currently available only in Python. Javascript/Typescript support coming soon! +{% /Banner %} Chroma supports multimodal collections, i.e. collections which can store, and can be queried by, multiple modalities of data. -Try it out in Colab: [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://githubtocolab.com/chroma-core/chroma/blob/main/examples/multimodal/multimodal_retrieval.ipynb) +[Try it out in Colab](https://githubtocolab.com/chroma-core/chroma/blob/main/examples/multimodal/multimodal_retrieval.ipynb) ## Multi-modal Embedding Functions @@ -36,7 +23,7 @@ embedding_function = OpenCLIPEmbeddingFunction() Chroma supports data loaders, for storing and querying with data stored outside Chroma itself, via URI. Chroma will not store this data, but will instead store the URI, and load the data from the URI when needed. -Chroma has an data loader for loading images from a filesystem built in. +Chroma has a data loader for loading images from a filesystem built in. ```python from chromadb.utils.data_loaders import ImageLoader @@ -140,11 +127,3 @@ collection.update( Note that a given entry with a specific ID can only have one associated modality at a time. Updates will over-write the existing modality, so for example, an entry which originally has corresponding text and updated with an image, will no longer have that text after an update with images. -{% /tab %} -{% tab label="Javascript" %} - -Support for multi-modal retrieval for Chroma's JavaScript client is coming soon! - -{% /tab %} - -{% /tabs %} diff --git a/docs/docs.trychroma.com/pages/guides/embeddings.md b/docs/docs.trychroma.com/markdoc/content/docs/guides/embeddings-guide.md similarity index 77% rename from docs/docs.trychroma.com/pages/guides/embeddings.md rename to docs/docs.trychroma.com/markdoc/content/docs/guides/embeddings-guide.md index d523c7d3089..5db0bcf7ddb 100644 --- a/docs/docs.trychroma.com/pages/guides/embeddings.md +++ b/docs/docs.trychroma.com/markdoc/content/docs/guides/embeddings-guide.md @@ -1,7 +1,14 @@ --- -title: '🧬 Embeddings' +{ + "id": "embeddings-guide", + "title": "Embeddings", + "section": "Guides", + "order": 1 +} --- +# Embeddings + Embeddings are the A.I-native way to represent any kind of data, making them the perfect fit for working with all kinds of A.I-powered tools and algorithms. They can represent text, images, and soon audio and video. There are many options for creating embeddings, whether locally using an installed library, or by calling an API. Chroma provides lightweight wrappers around popular embedding providers, making it easy to use them in your apps. You can set an embedding function when you create a Chroma collection, which will be used automatically, or you can call them directly yourself. @@ -41,37 +48,6 @@ val = default_ef(["foo"]) {% /note %} - - {% tabs group="code-lang" hideTabs=true %} {% tab label="Python" %} diff --git a/docs/docs.trychroma.com/markdoc/content/docs/guides/multimodal-guide.md b/docs/docs.trychroma.com/markdoc/content/docs/guides/multimodal-guide.md new file mode 100644 index 00000000000..70d7b30e5dc --- /dev/null +++ b/docs/docs.trychroma.com/markdoc/content/docs/guides/multimodal-guide.md @@ -0,0 +1,158 @@ +--- +{ + "id": "multimodal-guide", + "title": "Multimodal", + "section": "Guides", + "order": 2 +} +--- + +# Multimodal + +{% tabs group="code-lang" hideContent=true %} + +{% tab label="Python" %} +{% /tab %} + +{% tab label="Javascript" %} +{% /tab %} + +{% /tabs %} + +--- + +{% tabs group="code-lang" hideTabs=true %} +{% tab label="Python" %} + +Chroma supports multimodal collections, i.e. collections which can store, and can be queried by, multiple modalities of data. + +Try it out in Colab: [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://githubtocolab.com/chroma-core/chroma/blob/main/examples/multimodal/multimodal_retrieval.ipynb) + +## Multi-modal Embedding Functions + +Chroma supports multi-modal embedding functions, which can be used to embed data from multiple modalities into a single embedding space. + +Chroma has the OpenCLIP embedding function built in, which supports both text and images. + +```python +from chromadb.utils.embedding_functions import OpenCLIPEmbeddingFunction +embedding_function = OpenCLIPEmbeddingFunction() +``` + +## Data Loaders + +Chroma supports data loaders, for storing and querying with data stored outside Chroma itself, via URI. Chroma will not store this data, but will instead store the URI, and load the data from the URI when needed. + +Chroma has an data loader for loading images from a filesystem built in. + +```python +from chromadb.utils.data_loaders import ImageLoader +data_loader = ImageLoader() +``` + +## Multi-modal Collections + +You can create a multi-modal collection by passing in a multi-modal embedding function. In order to load data from a URI, you must also pass in a data loader. + +```python +import chromadb + +client = chromadb.Client() + +collection = client.create_collection( + name='multimodal_collection', + embedding_function=embedding_function, + data_loader=data_loader) + +``` + +### Adding data + +You can add data to a multi-modal collection by specifying the data modality. For now, images are supported: + +```python +collection.add( + ids=['id1', 'id2', 'id3'], + images=[...] # A list of numpy arrays representing images +) +``` + +Note that Chroma will not store the data for you, and you will have to maintain a mapping from IDs to data yourself. + +However, you can use Chroma in combination with data stored elsewhere, by adding it via URI. Note that this requires that you have specified a data loader when creating the collection. + +```python +collection.add( + ids=['id1', 'id2', 'id3'], + uris=[...] # A list of strings representing URIs to data +) +``` + +Since the embedding function is multi-modal, you can also add text to the same collection: + +```python +collection.add( + ids=['id4', 'id5', 'id6'], + documents=["This is a document", "This is another document", "This is a third document"] +) +``` + +### Querying + +You can query a multi-modal collection with any of the modalities that it supports. For example, you can query with images: + +```python +results = collection.query( + query_images=[...] # A list of numpy arrays representing images +) +``` + +Or with text: + +```python +results = collection.query( + query_texts=["This is a query document", "This is another query document"] +) +``` + +If a data loader is set for the collection, you can also query with URIs which reference data stored elsewhere of the supported modalities: + +```python +results = collection.query( + query_uris=[...] # A list of strings representing URIs to data +) +``` + +Additionally, if a data loader is set for the collection, and URIs are available, you can include the data in the results: + +```python +results = collection.query( + query_images=[...], # # list of numpy arrays representing images + includes=['data'] +) +``` + +This will automatically call the data loader for any available URIs, and include the data in the results. `uris` are also available as an `includes` field. + +### Updating + +You can update a multi-modal collection by specifying the data modality, in the same way as `add`. For now, images are supported: + +```python +collection.update( + ids=['id1', 'id2', 'id3'], + images=[...] # A list of numpy arrays representing images +) +``` + +Note that a given entry with a specific ID can only have one associated modality at a time. Updates will over-write the existing modality, so for example, an entry which originally has corresponding text and updated with an image, will no longer have that text after an update with images. + +{% /tab %} +{% tab label="Javascript" %} + +Support for multi-modal retrieval for Chroma's JavaScript client is coming soon! + +{% /tab %} + +{% /tabs %} + diff --git a/docs/docs.trychroma.com/pages/guides/index.md b/docs/docs.trychroma.com/markdoc/content/docs/guides/usage-guide.md similarity index 98% rename from docs/docs.trychroma.com/pages/guides/index.md rename to docs/docs.trychroma.com/markdoc/content/docs/guides/usage-guide.md index 54ec5eb2243..ce37ff89487 100644 --- a/docs/docs.trychroma.com/pages/guides/index.md +++ b/docs/docs.trychroma.com/markdoc/content/docs/guides/usage-guide.md @@ -1,7 +1,16 @@ --- -title: "🧪 Usage Guide" +{ + "id": "usage-guide", + "title": "Usage Guide", + "section": "Guides", + "order": 0 +} --- + +# Usage Guide + + {% tabs group="code-lang" hideContent=true %} {% tab label="Python" %} @@ -84,7 +93,7 @@ await client.reset() # Empties and completely resets the database. ⚠️ This i Chroma can also be configured to run in client/server mode. In this mode, the Chroma client connects to a Chroma server running in a separate process. -To start the Chroma server locally, run the following command: +To start the Chroma server, run the following command: ```bash chroma run --path /db_path @@ -165,7 +174,7 @@ To run Chroma in client server mode, first install the chroma library and CLI vi pip install chromadb ``` -Then start the Chroma server locally: +Then start the Chroma server: ```bash chroma run --path /db_path @@ -183,7 +192,7 @@ import { ChromaClient } from "chromadb"; const client = new ChromaClient(); ``` -You can also run the Chroma server in a docker container, or deployed to a cloud provider. See the [deployment docs](./deployment/docker) for more information. +You can also run the Chroma server in a docker container, or deployed to a cloud provider. See the [deployment docs](./deployment.md) for more information. {% /tab %} @@ -431,9 +440,9 @@ You can also store documents elsewhere, and just supply a list of `embeddings` a ```python collection.add( + ids=["id1", "id2", "id3", ...], embeddings=[[1.1, 2.3, 3.2], [4.5, 6.9, 4.4], [1.1, 2.3, 3.2], ...], - metadatas=[{"chapter": "3", "verse": "16"}, {"chapter": "3", "verse": "5"}, {"chapter": "29", "verse": "11"}, ...], - ids=["id1", "id2", "id3", ...] + metadatas=[{"chapter": "3", "verse": "16"}, {"chapter": "3", "verse": "5"}, {"chapter": "29", "verse": "11"}, ...] ) ``` @@ -624,7 +633,6 @@ Using the $eq operator is equivalent to using the `where` filter. "$eq": "search_string" } } - ``` {% note type="note" %} diff --git a/docs/docs.trychroma.com/pages/about.md b/docs/docs.trychroma.com/markdoc/content/docs/overview/about.md similarity index 91% rename from docs/docs.trychroma.com/pages/about.md rename to docs/docs.trychroma.com/markdoc/content/docs/overview/about.md index 576fec97de0..8592e16e356 100644 --- a/docs/docs.trychroma.com/pages/about.md +++ b/docs/docs.trychroma.com/markdoc/content/docs/overview/about.md @@ -1,14 +1,21 @@ --- -title: "👽 About" +{ + "id": "about", + "title": "About", + "section": "Overview", + "order": 4 +} --- -## Who we are +# About -{% note type="tip" title="We are hiring" %} +{% Banner type="tip" title="We are hiring" %} We are hiring software engineers and applied research scientists. -{% /note %} +{% /Banner %} + +## Who we are -[➡️ View open roles](https://careers.trychroma.com/) +[View open roles](https://careers.trychroma.com/) Chroma as a project is coordinated by a small team of full-time employees who work at a company also called Chroma. @@ -16,7 +23,7 @@ We work in the sunny Mission District in San Francisco. Chroma is co-founded by [Jeff Huber](https://twitter.com/jeffreyhuber) (left) and [Anton Troynikov](https://twitter.com/atroyn) (right). -![](/img/team.JPG) +![](/team.JPG) ## Our commitment to open source @@ -41,7 +48,9 @@ Currently we don’t have any specific plans to monetize Chroma, we are working Chroma raised an $18M seed round led by Astasia Myers from Quiet Capital. Joining the round are angels including Naval Ravikant, Max and Jack Altman, Jordan Tigani (Motherduck), Guillermo Rauch (Vercel), Akshay Kothari (Notion), Amjad Masad (Replit), Spencer Kimball (CockroachDB), and other founders and leaders from ScienceIO, Gumroad, MongoDB, Scale, Hugging Face, Jasper and more. -![](https://www.trychroma.com/investors.png) +{% CenteredContent %} +![chroma-investors](/investors.png) +{% /CenteredContent %} Chroma raised a pre-seed in May 2022, led by Anthony Goldbloom (Kaggle) from AIX Ventures, James Cham from Bloomberg Beta, and Nat Friedman and Daniel Gross (AI Grant). diff --git a/docs/docs.trychroma.com/pages/contributing.md b/docs/docs.trychroma.com/markdoc/content/docs/overview/contributing.md similarity index 82% rename from docs/docs.trychroma.com/pages/contributing.md rename to docs/docs.trychroma.com/markdoc/content/docs/overview/contributing.md index 17d28df8850..f7aa331d432 100644 --- a/docs/docs.trychroma.com/pages/contributing.md +++ b/docs/docs.trychroma.com/markdoc/content/docs/overview/contributing.md @@ -1,7 +1,14 @@ --- -title: "🍻 Contributing" +{ + "id": "contributing", + "title": "Contributing", + "section": "Overview", + "order": 3 +} --- +# Contributing + We welcome all contributions, bug reports, bug fixes, documentation improvements, enhancements, and ideas. ## Getting Started @@ -17,7 +24,7 @@ Here are some helpful links to get you started with contributing to Chroma ## Contributing Code and Ideas ### Pull Requests -In order to submit a change to Chroma please submit a [Pull Request](https://github.com/chroma-core/chroma/compare) against Chroma or the documentation. The pull request will be reviewed by the Chroma team and if approved will be merged into the repository. We will do our best to review pull requests in a timely manner but please be patient as we are a small team. We will work to integrate your prpoosed changes as quickly as possible if they align with the goals of the project. We ask that you label your pull request with a title prefix that indicates the type of change you are proposing. The following prefixes are used: +In order to submit a change to Chroma please submit a [Pull Request](https://github.com/chroma-core/chroma/compare) against Chroma or the documentation. The pull request will be reviewed by the Chroma team and if approved, will be merged into the repository. We will do our best to review pull requests in a timely manner but please be patient as we are a small team. We will work to integrate your proposed changes as quickly as possible if they align with the goals of the project. We ask that you label your pull request with a title prefix that indicates the type of change you are proposing. The following prefixes are used: ``` ENH: Enhancement, new functionality @@ -33,7 +40,7 @@ CHORE: Maintenance and other tasks that do not modify source or test files ### CIPs -Chroma Improvement Proposals or CIPs (pronounced "Chips") are the way to propose new features or large changes to Chroma. If you plan to make a large change to Chroma please submit a CIP first so that the core Chroma team as well as the community can discuss the proposed change and provide feedback. A CIP should provide a concise technical specification of the feature and a rationale for why it is needed. The CIP should be submitted as a pull request to the [CIPs folder](https://github.com/chroma-core/chroma/tree/main/docs). The CIP will be reviewed by the Chroma team and if approved will be merged into the repository. To learn more about writing a CIP you can read the [guide](https://github.com/chroma-core/chroma/blob/main/docs/cip/CIP_Chroma_Improvment_Proposals.md). CIPs are not required for small changes such as bug fixes or documentation updates. +Chroma Improvement Proposals or CIPs (pronounced "Chips") are the way to propose new features or large changes to Chroma. If you plan to make a large change to Chroma please submit a CIP first so that the core Chroma team as well as the community can discuss the proposed change and provide feedback. A CIP should provide a concise technical specification of the feature and a rationale for why it is needed. The CIP should be submitted as a pull request to the [CIPs folder](https://github.com/chroma-core/chroma/tree/main/docs). The CIP will be reviewed by the Chroma team and if approved will be merged into the repository. To learn more about writing a CIP you can read the [guide](https://github.com/chroma-core/chroma/blob/main/docs/CIP_Chroma_Improvment_Proposals.md). CIPs are not required for small changes such as bug fixes or documentation updates. A CIP starts in the "Proposed" state, then moves to "Under Review" once the Chroma team has reviewed it and is considering it for implementation. Once the CIP is approved it will move to the "Accepted" state and the implementation can begin. Once the implementation is complete the CIP will move to the "Implemented" state. If the CIP is not approved it will move to the "Rejected" state. If the CIP is withdrawn by the author it will move to the "Withdrawn" state. diff --git a/docs/docs.trychroma.com/markdoc/content/docs/overview/getting-started.md b/docs/docs.trychroma.com/markdoc/content/docs/overview/getting-started.md new file mode 100644 index 00000000000..1885977df38 --- /dev/null +++ b/docs/docs.trychroma.com/markdoc/content/docs/overview/getting-started.md @@ -0,0 +1,315 @@ +--- +{ + "id": "getting-started", + "title": "Getting Started", + "section": "Overview", + "order": 1 +} +--- + +# Getting Started + +Chroma is an AI-native open-source vector database. It comes with everything you need to get started built in, and runs on your machine. A [hosted version](https://airtable.com/shrOAiDUtS2ILy5vZ) is coming soon! + +### 1. Install + +{% Tabs %} + +{% Tab label="python" %} + +```terminal +pip install chromadb +``` + +{% /Tab %} + +{% Tab label="typescript" %} + +{% TabbedUseCaseCodeBlock language="Terminal" %} + +{% Tab label="yarn" %} +```terminal +yarn install chromadb chromadb-default-embed +``` +{% /Tab %} + +{% Tab label="npm" %} +```terminal +npm install --save chromadb chromadb-default-embed +``` +{% /Tab %} + +{% Tab label="pnpm" %} +```terminal +pnpm install chromadb chromadb-default-embed +``` +{% /Tab %} + +{% /TabbedUseCaseCodeBlock %} + +Install chroma via `pip` to easily run the backend server. Here are [instructions](https://pip.pypa.io/en/stable/installation/) for installing and running `pip`. Alternatively, you can also run Chroma in a [Docker](../../production/containers/docker) container. + +```terminal +pip install chromadb +``` + +{% /Tab %} + +{% /Tabs %} + +### 2. Create a Chroma Client + +{% Tabs %} + +{% Tab label="python" %} +```python +import chromadb +chroma_client = chromadb.Client() +``` +{% /Tab %} +{% Tab label="typescript" %} + +Run the Chroma backend: + +{% TabbedUseCaseCodeBlock language="Terminal" %} + +{% Tab label="CLI" %} +```terminal +chroma run --path ./getting-started +``` +{% /Tab %} + +{% Tab label="Docker" %} +```terminal +docker pull chromadb/chroma +docker run -p 8000:8000 chromadb/chroma +``` +{% /Tab %} + +{% /TabbedUseCaseCodeBlock %} + +Then create a client which connects to it: + +{% TabbedUseCaseCodeBlock language="typescript" %} + +{% Tab label="ESM" %} +```typescript +import { ChromaClient } from "chromadb"; +const client = new ChromaClient(); +``` +{% /Tab %} + +{% Tab label="CJS" %} +```typescript +const { ChromaClient } = require("chromadb"); +const client = new ChromaClient(); +``` +{% /Tab %} + +{% /TabbedUseCaseCodeBlock %} + +{% /Tab %} + +{% /Tabs %} + +### 3. Create a collection + +Collections are where you'll store your embeddings, documents, and any additional metadata. Collections index your embeddings and documents, and enable efficient retrieval and filtering. You can create a collection with a name: + +{% TabbedCodeBlock %} + +{% Tab label="python" %} +```python +collection = chroma_client.create_collection(name="my_collection") +``` +{% /Tab %} + +{% Tab label="typescript" %} +```typescript +const collection = await client.createCollection({ + name: "my_collection", +}); +``` +{% /Tab %} + +{% /TabbedCodeBlock %} + +### 4. Add some text documents to the collection + +Chroma will store your text and handle embedding and indexing automatically. You can also customize the embedding model. You must provide unique string IDs for your documents. + +{% TabbedCodeBlock %} + +{% Tab label="python" %} +```python +collection.add( + documents=[ + "This is a document about pineapple", + "This is a document about oranges" + ], + ids=["id1", "id2"] +) +``` +{% /Tab %} + +{% Tab label="typescript" %} +```typescript +await collection.add({ + documents: [ + "This is a document about pineapple", + "This is a document about oranges", + ], + ids: ["id1", "id2"], +}); +``` +{% /Tab %} + +{% /TabbedCodeBlock %} + +### 5. Query the collection + +You can query the collection with a list of query texts, and Chroma will return the `n` most similar results. It's that easy! + +{% TabbedCodeBlock %} + +{% Tab label="python" %} +```python +results = collection.query( + query_texts=["This is a query document about hawaii"], # Chroma will embed this for you + n_results=2 # how many results to return +) +print(results) +``` + +{% /Tab %} + +{% Tab label="typescript" %} +```typescript +const results = await collection.query({ + queryTexts: "This is a query document about hawaii", // Chroma will embed this for you + nResults: 2, // how many results to return +}); + +console.log(results); +``` +{% /Tab %} + +{% /TabbedCodeBlock %} + +If `n_results` is not provided, Chroma will return 10 results by default. Here we only added 2 documents, so we set `n_results=2`. + +### 6. Inspect Results + +From the above query - you can see that our query about `hawaii` is the semantically most similar to the document about `pineapple`. + +{% TabbedCodeBlock %} + +{% Tab label="python" %} +```python +{ + 'documents': [[ + 'This is a document about pineapple', + 'This is a document about oranges' + ]], + 'ids': [['id1', 'id2']], + 'distances': [[1.0404009819030762, 1.243080496788025]], + 'uris': None, + 'data': None, + 'metadatas': [[None, None]], + 'embeddings': None, +} +``` +{% /Tab %} + +{% Tab label="typescript" %} +```typescript +{ + documents: [ + [ + 'This is a document about pineapple', + 'This is a document about oranges' + ] + ], + ids: [ + ['id1', 'id2'] + ], + distances: [[1.0404009819030762, 1.243080496788025]], + uris: null, + data: null, + metadatas: [[null, null]], + embeddings: null +} +``` +{% /Tab %} + +{% /TabbedCodeBlock %} + +### 7. Try it out yourself + +For example - what if we tried querying with `"This is a document about florida"`? + +{% TabbedCodeBlock %} + +{% Tab label="python" %} +```python +import chromadb +chroma_client = chromadb.Client() + +# switch `create_collection` to `get_or_create_collection` to avoid creating a new collection every time +collection = chroma_client.get_or_create_collection(name="my_collection") + +# switch `add` to `upsert` to avoid adding the same documents every time +collection.upsert( + documents=[ + "This is a document about pineapple", + "This is a document about oranges" + ], + ids=["id1", "id2"] +) + +results = collection.query( + query_texts=["This is a query document about florida"], # Chroma will embed this for you + n_results=2 # how many results to return +) + +print(results) +``` +{% /Tab %} + +{% Tab label="typescript" %} +```typescript +import { ChromaClient } from "chromadb"; +const client = new ChromaClient(); + +// switch `createCollection` to `getOrCreateCollection` to avoid creating a new collection every time +const collection = await client.getOrCreateCollection({ + name: "my_collection", +}); + +// switch `addRecords` to `upsertRecords` to avoid adding the same documents every time +await collection.upsert({ + documents: [ + "This is a document about pineapple", + "This is a document about oranges", + ], + ids: ["id1", "id2"], +}); + +const results = await collection.query({ + queryTexts: "This is a query document about florida", // Chroma will embed this for you + nResults: 2, // how many results to return +}); + +console.log(results); +``` +{% /Tab %} + +{% /TabbedCodeBlock %} + +## Next steps + +In this guide we used Chroma's [ephemeral client](../run-chroma/ephemeral-client) for simplicity. It starts a Chroma server in-memory, so any data you ingest will be lost when your program terminates. You can use the [persistent client](../run-chroma/persistent-client) or run Chroma in [client-server mode](../run-chroma/client-server) if you need data persistence. + +- Learn how to [Deploy Chroma](../../production/deployment) to a server +- Join Chroma's [Discord Community](https://discord.com/invite/MMeYNTmh3x) to ask questions and get help +- Follow Chroma on [Twitter (@trychroma)](https://twitter.com/trychroma) for updates diff --git a/docs/docs.trychroma.com/markdoc/content/docs/overview/introduction.md b/docs/docs.trychroma.com/markdoc/content/docs/overview/introduction.md new file mode 100644 index 00000000000..601f7e79183 --- /dev/null +++ b/docs/docs.trychroma.com/markdoc/content/docs/overview/introduction.md @@ -0,0 +1,92 @@ +--- +{ + "id": "introduction", + "title": "Introduction", + "section": "Overview", + "order": 0 +} +--- + +# Chroma + +**Chroma is the open-source AI application database**. Chroma makes it easy to build LLM apps by making knowledge, facts, and skills pluggable for LLMs. + +{% Banner type="tip" %} +New to Chroma? Check out the [getting started guide](./getting-started) +{% /Banner %} + +![Chroma Computer](/computer.svg) + +Chroma gives you everything you need for retrieval: + +- Store embeddings and their metadata +- Vector search +- Full-text search +- Document storage +- Metadata filtering +- Multi-modal retrieval + +Chroma runs as a server and provides `Python` and `JavaScript/TypeScript` client SDKs. Check out the [Colab demo](https://colab.research.google.com/drive/1QEzFyqnoFxq7LUGyP1vzR4iLt9PpCDXv?usp=sharing) (yes, it can run in a Jupyter notebook). + +Chroma is licensed under [Apache 2.0](https://github.com/chroma-core/chroma/blob/main/LICENSE) + +### Python +In Python, Chroma can run in a python script or as a server. Install Chroma with + +```shell +pip install chromadb +``` + +### JavaScript +In JavaScript, use the Chroma JS/TS Client to connect to a Chroma server. Install Chroma with your favorite package manager: + +{% TabbedUseCaseCodeBlock language="Terminal" %} + +{% Tab label="yarn" %} +```terminal +yarn install chromadb chromadb-default-embed +``` +{% /Tab %} + +{% Tab label="npm" %} +```terminal +npm install --save chromadb chromadb-default-embed +``` +{% /Tab %} + +{% Tab label="pnpm" %} +```terminal +pnpm install chromadb chromadb-default-embed +``` +{% /Tab %} + +{% /TabbedUseCaseCodeBlock %} + + +Continue with the full [getting started guide](./getting-started). + + +*** + +### Language Clients + +| Language | Client | +|---------------|--------------------------------------------------------------------------------------------------------------------------| +| Python | [`chromadb`](https://pypistats.org/packages/chromadb) (by Chroma) | +| Javascript | [`chromadb`](https://www.npmjs.com/package/chromadb) (by Chroma) | +| Ruby | [from @mariochavez](https://github.com/mariochavez/chroma) | +| Java | [from @t_azarov](https://github.com/amikos-tech/chromadb-java-client) | +| Go | [from @t_azarov](https://github.com/amikos-tech/chroma-go) | +| C# | [from @microsoft](https://github.com/microsoft/semantic-kernel/tree/main/dotnet/src/Connectors/Connectors.Memory.Chroma) | +| Rust | [from @Anush008](https://crates.io/crates/chromadb) | +| Elixir | [from @3zcurdia](https://hex.pm/packages/chroma/) | +| Dart | [from @davidmigloz](https://pub.dev/packages/chromadb) | +| PHP | [from @CodeWithKyrian](https://github.com/CodeWithKyrian/chromadb-php) | +| PHP (Laravel) | [from @HelgeSverre](https://github.com/helgeSverre/chromadb) | +| Clojure | [from @levand](https://github.com/levand/clojure-chroma-client) | + + +{% br %}{% /br %} + +We welcome [contributions](/markdoc/content/docs/overview/contributing.md) for other languages! + diff --git a/docs/docs.trychroma.com/pages/roadmap.md b/docs/docs.trychroma.com/markdoc/content/docs/overview/roadmap.md similarity index 64% rename from docs/docs.trychroma.com/pages/roadmap.md rename to docs/docs.trychroma.com/markdoc/content/docs/overview/roadmap.md index 701a7914419..2bfbba8b1a5 100644 --- a/docs/docs.trychroma.com/pages/roadmap.md +++ b/docs/docs.trychroma.com/markdoc/content/docs/overview/roadmap.md @@ -1,10 +1,14 @@ --- -title: "🛣️ Roadmap" +{ + "id": "roadmap", + "title": "Roadmap", + "section": "Overview", + "order": 2 +} --- -{% note type="default" title="Last Updated" %} -`May 20, 2024` -{% /note %} + +# Roadmap The goal of this doc is to align *core* and *community* efforts for the project and to share what's in store for this year! @@ -15,15 +19,15 @@ The goal of this doc is to align *core* and *community* efforts for the project ## What is the core Chroma team working on right now? -- 🌩️ Standing up that distributed system as a managed service (aka "Hosted Chroma" - [sign up for waitlist](https://airtable.com/shrOAiDUtS2ILy5vZ)!) +- Standing up that distributed system as a managed service (aka "Hosted Chroma" - [sign up for waitlist](https://airtable.com/shrOAiDUtS2ILy5vZ)!) ## What did the Chroma team just complete? Features like: - *New* - [Chroma 0.4](https://www.trychroma.com/blog/chroma_0.4.0) - our first production-oriented release -- 🐍 A more minimal python-client only build target -- ✋ Google PaLM embedding support -- 🎣 OpenAI ChatGPT Retrieval Plugin +- A more minimal python-client only build target +- Google PaLM embedding support +- OpenAI ChatGPT Retrieval Plugin ## What will Chroma prioritize over the next 6mo? @@ -33,13 +37,13 @@ Features like: Not an exhaustive list, but these are some of the core team’s biggest priorities over the coming few months. Use caution when contributing in these areas and please check-in with the core team first. -- ⏩ **Workflow**: Building tools for answer questions like: what embedding model should I use? And how should I chunk up my documents? -- 🌌 **Visualization**: Building visualization tool to give developers greater intuition embedding spaces -- 🔀 **Query Planner**: Building tools to enable per-query and post-query transforms -- 🔧 **Developer experience**: Extending Chroma into a CLI -- 📦 **Easier Data Sharing**: Working on formats for serialization and easier data sharing of embedding Collections -- 🔍 **Improving recall**: Fine-tuning embedding transforms through human feedback -- 🧠 **Analytical horsepower**: Clustering, deduplication, classification and more +- **Workflow**: Building tools for answer questions like: what embedding model should I use? And how should I chunk up my documents? +- **Visualization**: Building visualization tool to give developers greater intuition embedding spaces +- **Query Planner**: Building tools to enable per-query and post-query transforms +- **Developer experience**: Extending Chroma into a CLI +- **Easier Data Sharing**: Working on formats for serialization and easier data sharing of embedding Collections +- **Improving recall**: Fine-tuning embedding transforms through human feedback +- **Analytical horsepower**: Clustering, deduplication, classification and more ## What areas are great for community contributions? @@ -47,17 +51,17 @@ This is where you have a lot more free reign to contribute (without having to sy If you're unsure about your contribution idea, feel free to chat with us (@chroma) in the `#general` channel in [our Discord](https://discord.gg/rahcMUU5XV)! We'd love to support you however we can. -### ⚙️ Example Templates +### Example Templates -We can always use [more integrations](https://docs.trychroma.com/integrations) with the rest of the AI ecosystem. Please let us know if you're working on one and need help! +We can always use [more integrations](../../integrations/chroma-integrations) with the rest of the AI ecosystem. Please let us know if you're working on one and need help! Other great starting points for Chroma (please send PRs for more [here](https://github.com/chroma-core/docs/tree/swyx/addRoadmap/docs)): - [Google Colab](https://colab.research.google.com/drive/1QEzFyqnoFxq7LUGyP1vzR4iLt9PpCDXv?usp=sharing) - [Replit Template](https://replit.com/@swyx/BasicChromaStarter?v=1) -For those integrations we do have, like `LangChain` and `LlamaIndex`, we do always want more tutorials, demos, workshops, videos, and podcasts (we've done some pods [on our blog](https://trychroma.com/blog)). +For those integrations we do have, like LangChain and LlamaIndex, we do always want more tutorials, demos, workshops, videos, and podcasts (we've done some pods [on our blog](https://trychroma.com/blog)). -### 📦 Example Datasets +### Example Datasets It doesn’t make sense for developers to embed the same information over and over again with the same embedding model. @@ -69,7 +73,7 @@ We'd like suggestions for: datasets for people to stress test Chroma in a variety of scenarios. -### ⚖️ Embeddings Comparison +### Embeddings Comparison Chroma does ship with Sentence Transformers by default for embeddings, but we are otherwise unopinionated about what embeddings you use. Having a library of information that has been embedded with many models, alongside example query sets would make it much easier for empirical work to be done on the effectiveness of various models across different domains. @@ -77,7 +81,7 @@ Chroma does ship with Sentence Transformers by default for embeddings, but we ar - [Huggingface Benchmark of a bunch of Embeddings](https://huggingface.co/blog/mteb) - [notable issues with GPT3 Embeddings](https://twitter.com/Nils_Reimers/status/1487014195568775173) and alternatives to consider -### ⚗️ Experimental Algorithms +### Experimental Algorithms If you have a research background, please consider adding to our `ExperimentalAPI`s. For example: @@ -89,14 +93,6 @@ If you have a research background, please consider adding to our `ExperimentalAP - Expanded vector search (MMR, Polytope) - Your research -### 🧑‍💻️ Additional Client SDKs - -We will be happy to work with people maintaining additional client SDKs as part of the community. Specifically: - -- Ruby -- Clojure -- Elixir - You can find the REST OpenAPI spec at `localhost:8000/openapi.json` when the backend is running. Please [reach out](https://discord.gg/MMeYNTmh3x) and talk to us before you get too far in your projects so that we can offer technical guidance/align on roadmap. diff --git a/docs/docs.trychroma.com/pages/telemetry.md b/docs/docs.trychroma.com/markdoc/content/docs/overview/telemetry.md similarity index 74% rename from docs/docs.trychroma.com/pages/telemetry.md rename to docs/docs.trychroma.com/markdoc/content/docs/overview/telemetry.md index c54e67ddbb1..b7f7e12d1b3 100644 --- a/docs/docs.trychroma.com/pages/telemetry.md +++ b/docs/docs.trychroma.com/markdoc/content/docs/overview/telemetry.md @@ -1,18 +1,20 @@ ---- -title: "📏 Telemetry" ---- +# Telemetry Chroma contains a telemetry feature that collects **anonymous** usage information. -## Why? +### Why? We use this information to help us understand how Chroma is used, to help us prioritize work on new features and bug fixes, and to help us improve Chroma’s performance and stability. -## Opting out +### Opting out If you prefer to opt out of telemetry, you can do this in two ways. -###### In Client Code +#### In Client Code + +{% Tabs %} + +{% Tab label="python" %} Set `anonymized_telemetry` to `False` in your client's settings: @@ -23,7 +25,17 @@ client = chromadb.Client(Settings(anonymized_telemetry=False)) client = chromadb.PersistentClient(path="/path/to/save/to", settings=Settings(anonymized_telemetry=False)) ``` -###### In Chroma's Backend Using Environment Variables +{% /Tab %} + +{% Tab label="typescript" %} + +Disable telemetry on you Chroma server (see next section). + +{% /Tab %} + +{% /Tabs %} + +#### In Chroma's Backend Using Environment Variables Set `ANONYMIZED_TELEMETRY` to `False` in your shell or server environment. @@ -33,7 +45,7 @@ If you are running Chroma on your local computer with `docker-compose` you can s ANONYMIZED_TELEMETRY=False ``` -## What do you track? +### What do you track? We will only track usage details that help us make product decisions, specifically: @@ -41,18 +53,22 @@ We will only track usage details that help us make product decisions, specifical - Usage of embedding functions that ship with Chroma and aggregated usage of custom embeddings (we collect no information about the custom embeddings themselves) - Client interactions with our hosted Chroma Cloud service. - Collection commands. We track the anonymized uuid of a collection as well as the number of items - - `add` - - `update` - - `query` - - `get` - - `delete` + - `add` + - `update` + - `query` + - `get` + - `delete` We **do not** collect personally-identifiable or sensitive information, such as: usernames, hostnames, file names, environment variables, or hostnames of systems being tested. To view the list of events we track, you may reference the **[code](https://github.com/chroma-core/chroma/blob/main/chromadb/telemetry/product/events.py)** -## Where is telemetry information stored? +### Where is telemetry information stored? We use **[Posthog](https://posthog.com/)** to store and visualize telemetry data. -> Posthog is an open source platform for product analytics. Learn more about Posthog on **[posthog.com](https://posthog.com/)** or **[github.com/posthog](https://github.com/posthog/posthog)** +{% Banner type="tip" %} + +Posthog is an open source platform for product analytics. Learn more about Posthog on **[posthog.com](https://posthog.com/)** or **[github.com/posthog](https://github.com/posthog/posthog)** + +{% /Banner %} \ No newline at end of file diff --git a/docs/docs.trychroma.com/markdoc/content/docs/querying-collections/full-text-search.md b/docs/docs.trychroma.com/markdoc/content/docs/querying-collections/full-text-search.md new file mode 100644 index 00000000000..81a0b147cf8 --- /dev/null +++ b/docs/docs.trychroma.com/markdoc/content/docs/querying-collections/full-text-search.md @@ -0,0 +1,43 @@ +# Full Text Search + +In order to filter on document contents, you must supply a `where_document` filter dictionary to the query. We support two filtering keys: `$contains` and `$not_contains`. The dictionary must have the following structure: + +```python +# Filtering for a search_string +{ + "$contains": "search_string" +} + +# Filtering for not contains +{ + "$not_contains": "search_string" +} +``` + +You can combine full-text search with Chroma's metadata filtering. + +{% TabbedCodeBlock %} + +{% Tab label="python" %} +```python +collection.query( + query_texts=["doc10", "thus spake zarathustra", ...], + n_results=10, + where={"metadata_field": "is_equal_to_this"}, + where_document={"$contains":"search_string"} +) +``` +{% /Tab %} + +{% Tab label="typescript" %} +```typescript +await collection.query({ + queryTexts: ["doc10", "thus spake zarathustra", ...], + nResults: 10, + where: {"metadata_field": "is_equal_to_this"}, + whereDocument: {"$contains": "search_string"} +}) +``` +{% /Tab %} + +{% /TabbedCodeBlock %} \ No newline at end of file diff --git a/docs/docs.trychroma.com/markdoc/content/docs/querying-collections/metadata-filtering.md b/docs/docs.trychroma.com/markdoc/content/docs/querying-collections/metadata-filtering.md new file mode 100644 index 00000000000..64fd2c062da --- /dev/null +++ b/docs/docs.trychroma.com/markdoc/content/docs/querying-collections/metadata-filtering.md @@ -0,0 +1,117 @@ +# Metadata Filtering + +Chroma supports filtering queries by `metadata` and `document` contents. The `where` filter is used to filter by `metadata`. + +In order to filter on metadata, you must supply a `where` filter dictionary to the query. The dictionary must have the following structure: + +```python +{ + "metadata_field": { + : + } +} +``` + +Filtering metadata supports the following operators: + +- `$eq` - equal to (string, int, float) +- `$ne` - not equal to (string, int, float) +- `$gt` - greater than (int, float) +- `$gte` - greater than or equal to (int, float) +- `$lt` - less than (int, float) +- `$lte` - less than or equal to (int, float) + +Using the `$eq` operator is equivalent to using the `where` filter. + +```python +{ + "metadata_field": "search_string" +} + +# is equivalent to + +{ + "metadata_field": { + "$eq": "search_string" + } +} +``` + +{% Banner type="note" %} +Where filters only search embeddings where the key exists. If you search `collection.get(where={"version": {"$ne": 1}})`. Metadata that does not have the key `version` will not be returned. +{% /Banner %} + +#### Using logical operators + +You can also use the logical operators `$and` and `$or` to combine multiple filters. + +An `$and` operator will return results that match all of the filters in the list. + +```python +{ + "$and": [ + { + "metadata_field": { + : + } + }, + { + "metadata_field": { + : + } + } + ] +} +``` + +An `$or` operator will return results that match any of the filters in the list. + +```python +{ + "$or": [ + { + "metadata_field": { + : + } + }, + { + "metadata_field": { + : + } + } + ] +} +``` + +#### Using inclusion operators (`$in` and `$nin`) + +The following inclusion operators are supported: + +- `$in` - a value is in predefined list (string, int, float, bool) +- `$nin` - a value is not in predefined list (string, int, float, bool) + +An `$in` operator will return results where the metadata attribute is part of a provided list: + +```json +{ + "metadata_field": { + "$in": ["value1", "value2", "value3"] + } +} +``` + +An `$nin` operator will return results where the metadata attribute is not part of a provided list: + +```json +{ + "metadata_field": { + "$nin": ["value1", "value2", "value3"] + } +} +``` + +{% Banner type="tip" %} + +For additional examples and a demo how to use the inclusion operators, please see provided notebook [here](https://github.com/chroma-core/chroma/blob/main/examples/basic_functionality/in_not_in_filtering.ipynb) + +{% /Banner %} \ No newline at end of file diff --git a/docs/docs.trychroma.com/markdoc/content/docs/querying-collections/query-and-get.md b/docs/docs.trychroma.com/markdoc/content/docs/querying-collections/query-and-get.md new file mode 100644 index 00000000000..55b06adb977 --- /dev/null +++ b/docs/docs.trychroma.com/markdoc/content/docs/querying-collections/query-and-get.md @@ -0,0 +1,126 @@ +# Query and Get Data from Chroma Collections + +Chroma collections can be queried in a variety of ways, using the `.query` method. + +You can query by a set of `query embeddings`. + +{% TabbedCodeBlock %} + +{% Tab label="python" %} +```python +collection.query( + query_embeddings=[[11.1, 12.1, 13.1],[1.1, 2.3, 3.2], ...], + n_results=10, + where={"metadata_field": "is_equal_to_this"}, + where_document={"$contains":"search_string"} +) +``` +{% /Tab %} + +{% Tab label="typescript" %} +```typescript +const result = await collection.query({ + queryEmbeddings: [[11.1, 12.1, 13.1],[1.1, 2.3, 3.2], ...], + nResults: 10, + where: {"metadata_field": "is_equal_to_this"}, +}) +``` +{% /Tab %} + +{% /TabbedCodeBlock %} + +The query will return the `n results` closest matches to each `query embedding`, in order. +An optional `where` filter dictionary can be supplied to filter by the `metadata` associated with each document. +Additionally, an optional `where document` filter dictionary can be supplied to filter by contents of the document. + +If the supplied `query embeddings` are not the same dimension as the collection, an exception will be raised. + +You can also query by a set of `query texts`. Chroma will first embed each `query text` with the collection's embedding function, and then perform the query with the generated embedding. + +{% TabbedCodeBlock %} + +{% Tab label="python" %} +```python +collection.query( + query_texts=["doc10", "thus spake zarathustra", ...], + n_results=10, + where={"metadata_field": "is_equal_to_this"}, + where_document={"$contains":"search_string"} +) +``` +{% /Tab %} + +{% Tab label="typescript" %} +```typescript +await collection.query({ + queryTexts: ["doc10", "thus spake zarathustra", ...], + nResults: 10, + where: {"metadata_field": "is_equal_to_this"}, + whereDocument: {"$contains": "search_string"} +}) +``` +{% /Tab %} + +{% /TabbedCodeBlock %} + +You can also retrieve items from a collection by `id` using `.get`. + +{% TabbedCodeBlock %} + +{% Tab label="python" %} +```python +collection.get( + ids=["id1", "id2", "id3", ...], + where={"style": "style1"} +) +``` +{% /Tab %} + +{% Tab label="typescript" %} +```typescript +await collection.get( { + ids: ["id1", "id2", "id3", ...], + where: {"style": "style1"} +}) +``` +{% /Tab %} + +{% /TabbedCodeBlock %} + +`.get` also supports the `where` and `where document` filters. If no `ids` are supplied, it will return all items in the collection that match the `where` and `where document` filters. + +### Choosing Which Data is Returned + +When using get or query you can use the `include` parameter to specify which data you want returned - any of `embeddings`, `documents`, `metadatas`, and for query, `distances`. By default, Chroma will return the `documents`, `metadatas` and in the case of query, the `distances` of the results. `embeddings` are excluded by default for performance and the `ids` are always returned. You can specify which of these you want returned by passing an array of included field names to the includes parameter of the query or get method. Note that embeddings will be returned as a 2-d numpy array in `.get` and a python list of 2-d numpy arrays in `.query`. + +{% TabbedCodeBlock %} + +{% Tab label="python" %} +```python +# Only get documents and ids +collection.get( + include=["documents"] +) + +collection.query( + query_embeddings=[[11.1, 12.1, 13.1],[1.1, 2.3, 3.2], ...], + include=["documents"] +) +``` +{% /Tab %} + +{% Tab label="typescript" %} +```typescript +// Only get documents and ids +await collection.get({ + include: ["documents"] +}) + +await collection.query({ + query_embeddings: [[11.1, 12.1, 13.1], [1.1, 2.3, 3.2], ...], + include: ["documents"] +}) +``` +{% /Tab %} + +{% /TabbedCodeBlock %} diff --git a/docs/docs.trychroma.com/markdoc/content/docs/run-chroma/client-server.md b/docs/docs.trychroma.com/markdoc/content/docs/run-chroma/client-server.md new file mode 100644 index 00000000000..a7bb3d77738 --- /dev/null +++ b/docs/docs.trychroma.com/markdoc/content/docs/run-chroma/client-server.md @@ -0,0 +1,59 @@ +# Running Chroma in Client-Server Mode + +Chroma can also be configured to run in client/server mode. In this mode, the Chroma client connects to a Chroma server running in a separate process. + +To start the Chroma server, run the following command: + +```terminal +chroma run --path /db_path +``` + +{% Tabs %} + +{% Tab label="python" %} + +Then use the Chroma HTTP client to connect to the server: + +```python +import chromadb + +chroma_client = chromadb.HttpClient(host='localhost', port=8000) +``` + +That's it! Chroma's API will run in `client-server` mode with just this change. + +Chroma also provides an async HTTP client. The behaviors and method signatures are identical to the synchronous client, but all methods that would block are now async. To use it, call `AsyncHttpClient` instead: + +```python +import asyncio +import chromadb + +async def main(): + client = await chromadb.AsyncHttpClient() + + collection = await client.create_collection(name="my_collection") + await collection.add( + documents=["hello world"], + ids=["id1"] + ) + +asyncio.run(main()) +``` + +If you [deploy](../../production/deployment) your Chroma server, you can also use our [http-only](./python-http-client) package. + +{% /Tab %} + +{% Tab label="typescript" %} + +Then you can connect to it by instantiating a new `ChromaClient`: + +```typescript +import { ChromaClient } from "chromadb"; + +const client = new ChromaClient(); +``` + +{% /Tab %} + +{% /Tabs %} diff --git a/docs/docs.trychroma.com/markdoc/content/docs/run-chroma/ephemeral-client.md b/docs/docs.trychroma.com/markdoc/content/docs/run-chroma/ephemeral-client.md new file mode 100644 index 00000000000..2def4b8127d --- /dev/null +++ b/docs/docs.trychroma.com/markdoc/content/docs/run-chroma/ephemeral-client.md @@ -0,0 +1,13 @@ +# Ephemeral Client + +In Python, you can run a Chroma server in-memory and connect to it with the ephemeral client: + +```python +import chromadb + +client = chromadb.Client() +``` + +The `Client()` method starts a Chroma server in-memory and also returns a client with which you can connect to it. + +This is a great tool for experimenting with different embedding functions and retrieval techniques in a Python notebook, for example. If you don't need data persistence, the ephemeral client is a good choice for getting up and running with Chroma. \ No newline at end of file diff --git a/docs/docs.trychroma.com/markdoc/content/docs/run-chroma/persistent-client.md b/docs/docs.trychroma.com/markdoc/content/docs/run-chroma/persistent-client.md new file mode 100644 index 00000000000..9aee0a9fc2a --- /dev/null +++ b/docs/docs.trychroma.com/markdoc/content/docs/run-chroma/persistent-client.md @@ -0,0 +1,82 @@ +# Persistent Client + +{% Tabs %} + +{% Tab label="python" %} + +You can configure Chroma to save and load the database from your local machine, using the `PersistentClient`. + +Data will be persisted automatically and loaded on start (if it exists). + +```python +import chromadb + +client = chromadb.PersistentClient(path="/path/to/save/to") +``` + +The `path` is where Chroma will store its database files on disk, and load them on start. If you don't provide a path, the default is `.chroma` + +{% /Tab %} + +{% Tab label="typescript" %} + +To connect with the JS/TS client, you must connect to a Chroma server. + +To run a Chroma server locally that will persist your data, install Chroma via `pip`: + +```terminal +pip install chromadb +``` + +And run the server using our CLI: + +```terminal +chroma run --path ./getting-started +``` + +The `path` is where Chroma will store its database files on disk, and load them on start. The default is `.chroma`. + +Alternatively, you can also use our official Docker image: + +```terminal +docker pull chromadb/chroma +docker run -p 8000:8000 chromadb/chroma +``` + +With a Chroma server running locally, you can connect to it by instantiating a new `ChromaClient`: + +```typescript +import { ChromaClient } from "chromadb"; + +const client = new ChromaClient(); +``` + +See [Running Chroma in client-server mode](../client-server-mode) for more. + +{% /Tab %} + +{% /Tabs %} + +The client object has a few useful convenience methods. + +* `hearthbeat()` - returns a nanosecond heartbeat. Useful for making sure the client remains connected. +* `reset()` - empties and completely resets the database. ⚠️ This is destructive and not reversible. + +{% TabbedCodeBlock %} + +{% Tab label="python" %} +```python +client.heartbeat() +client.reset() +``` +{% /Tab %} + +{% Tab label="typescript" %} +```typescript +await client.heartbeat(); +await client.reset(); +``` +{% /Tab %} + +{% /TabbedCodeBlock %} + diff --git a/docs/docs.trychroma.com/markdoc/content/docs/run-chroma/python-http-client.md b/docs/docs.trychroma.com/markdoc/content/docs/run-chroma/python-http-client.md new file mode 100644 index 00000000000..5aa154053a8 --- /dev/null +++ b/docs/docs.trychroma.com/markdoc/content/docs/run-chroma/python-http-client.md @@ -0,0 +1,35 @@ +# The Python HTTP-Only Client + +If you are running Chroma in client-server mode, where you run a Chroma server and client on separate machines, you may not need the full Chroma package where you run your client. Instead, you can use the lightweight client-only library. +In this case, you can install the `chromadb-client` package. This package is a lightweight HTTP client for the server with a minimal dependency footprint. + +On your server, install chroma with + +```terminal +pip install chromadb +``` + +And run a Chroma server: + +```terminal +chroma run --path [path/to/persist/data] +``` + +Then, on your client side, install the HTTP-only client: + +```terminal +pip install chromadb-client +``` + +```python +import chromadb +# Example setup of the client to connect to your chroma server +client = chromadb.HttpClient(host='localhost', port=8000) + +# Or for async usage: +async def main(): + client = await chromadb.AsyncHttpClient(host='localhost', port=8000) +``` + +Note that the `chromadb-client` package is a subset of the full Chroma library and does not include all the dependencies. If you want to use the full Chroma library, you can install the `chromadb` package instead. +Most importantly, there is no default embedding function. If you add() documents without embeddings, you must have manually specified an embedding function and installed the dependencies for it. diff --git a/docs/docs.trychroma.com/markdoc/content/integrations/chroma-integrations.md b/docs/docs.trychroma.com/markdoc/content/integrations/chroma-integrations.md new file mode 100644 index 00000000000..4068ab88d63 --- /dev/null +++ b/docs/docs.trychroma.com/markdoc/content/integrations/chroma-integrations.md @@ -0,0 +1,44 @@ +# Integrations + +### Embedding Integrations + +Embeddings are the A.I-native way to represent any kind of data, making them the perfect fit for working with all kinds of A.I-powered tools and algorithms. They can represent text, images, and soon audio and video. There are many options for creating embeddings, whether locally using an installed library, or by calling an API. + +Chroma provides lightweight wrappers around popular embedding providers, making it easy to use them in your apps. You can set an embedding function when you create a Chroma collection, which will be used automatically, or you can call them directly yourself. + +{% special_table %} +{% /special_table %} + +| | Python | Typescript | +|-------------------------------------------------------------------------|--|------------| +| [OpenAI](./embedding-models/openai) | ✓ | ✓ | +| [Google Gemini](./embedding-models/google-gemini) | ✓ | ✓ | +| [Cohere](./embedding-models/cohere) | ✓ | ✓ | +| [Hugging Face](./embedding-models/hugging-face) | ✓ | - | +| [Instructor](./embedding-models/instructor) | ✓ | - | +| [Hugging Face Embedding Server](./embedding-models/hugging-face-server) | ✓ | ✓ | +| [Jina AI](./embedding-models/jina-ai) | ✓ | ✓ | +| [Roboflow](./embedding-models/roboflow) | ✓ | - | +| [Ollama Embeddings](./embedding-models/ollama) | ✓ | ✓ | + + +*** + +### Framework Integrations + +Chroma maintains integrations with many popular tools. These tools can be used to define the business logic of an AI-native application, curate data, fine-tune embedding spaces and more. + +We welcome pull requests to add new Integrations to the community. + +{% special_table %} +{% /special_table %} + +| | Python | JS | +|---------------------------------------|----|--------------| +| [Langchain](./frameworks/langchain) | ✓ | ✓ | +| [LlamaIndex](./frameworks/llamaindex) | ✓ | ✓ | +| [Braintrust](./frameworks/braintrust) | ✓ | ✓ | +| [OpenLLMetry](./frameworks/openllmetry) | ✓ | Coming Soon! | +| [Streamlit](./frameworks/streamlit) | ✓ | - | +| [Haystack](./frameworks/haystack) | ✓ | - | +| [OpenLIT](./frameworks/openlit) | ✓ | Coming Soon! | diff --git a/docs/docs.trychroma.com/pages/integrations/cohere.md b/docs/docs.trychroma.com/markdoc/content/integrations/embedding-models/cohere.md similarity index 80% rename from docs/docs.trychroma.com/pages/integrations/cohere.md rename to docs/docs.trychroma.com/markdoc/content/integrations/embedding-models/cohere.md index c69bbc0bb46..2adbf9fa718 100644 --- a/docs/docs.trychroma.com/pages/integrations/cohere.md +++ b/docs/docs.trychroma.com/markdoc/content/integrations/embedding-models/cohere.md @@ -1,18 +1,14 @@ --- -title: 'Cohere' +id: 'cohere' +name: 'Cohere' --- -{% tabs group="code-lang" hideContent=true %} -{% tab label="Python" %} -{% /tab %} -{% tab label="Javascript" %} -{% /tab %} -{% /tabs %} +# Cohere Chroma also provides a convenient wrapper around Cohere's embedding API. This embedding function runs remotely on Cohere’s servers, and requires an API key. You can get an API key by signing up for an account at [Cohere](https://dashboard.cohere.ai/welcome/register). -{% tabs group="code-lang" hideTabs=true %} -{% tab label="Python" %} +{% Tabs %} +{% Tab label="python" %} This embedding function relies on the `cohere` python package, which you can install with `pip install cohere`. @@ -22,11 +18,13 @@ cohere_ef = embedding_functions.CohereEmbeddingFunction(api_key="YOUR_API_KEY", cohere_ef(texts=["document1","document2"]) ``` -{% /tab %} -{% tab label="Javascript" %} +{% /Tab %} + +{% Tab label="typescript" %} + +```typescript +import { CohereEmbeddingFunction } from 'chromadb'; -```javascript -const {CohereEmbeddingFunction} = require('chromadb'); const embedder = new CohereEmbeddingFunction("apiKey") // use directly @@ -37,18 +35,17 @@ const collection = await client.createCollection({name: "name", embeddingFunctio const collectionGet = await client.getCollection({name:"name", embeddingFunction: embedder}) ``` -{% /tab %} -{% /tabs %} - +{% /Tab %} +{% /Tabs %} You can pass in an optional `model_name` argument, which lets you choose which Cohere embeddings model to use. By default, Chroma uses `large` model. You can see the available models under `Get embeddings` section [here](https://docs.cohere.ai/reference/embed). - ### Multilingual model example -{% tabs group="code-lang" hideTabs=true %} -{% tab label="Python" %} +{% TabbedCodeBlock %} + +{% Tab label="python" %} ```python cohere_ef = embedding_functions.CohereEmbeddingFunction( @@ -65,11 +62,13 @@ cohere_ef(texts=multilingual_texts) ``` -{% /tab %} -{% tab label="Javascript" %} +{% /Tab %} + +{% Tab label="typescript" %} + +```typescript +import { CohereEmbeddingFunction } from 'chromadb'; -```javascript -const {CohereEmbeddingFunction} = require('chromadb'); const embedder = new CohereEmbeddingFunction("apiKey") multilingual_texts = [ 'Hello from Cohere!', 'مرحبًا من كوهير!', @@ -82,8 +81,8 @@ const embeddings = embedder.generate(multilingual_texts) ``` +{% /Tab %} -{% /tab %} -{% /tabs %} +{% /TabbedCodeBlock %} For more information on multilingual model you can read [here](https://docs.cohere.ai/docs/multilingual-language-models). diff --git a/docs/docs.trychroma.com/pages/integrations/google-gemini.md b/docs/docs.trychroma.com/markdoc/content/integrations/embedding-models/google-gemini.md similarity index 86% rename from docs/docs.trychroma.com/pages/integrations/google-gemini.md rename to docs/docs.trychroma.com/markdoc/content/integrations/embedding-models/google-gemini.md index 74bfe69c8b9..68fda099833 100644 --- a/docs/docs.trychroma.com/pages/integrations/google-gemini.md +++ b/docs/docs.trychroma.com/markdoc/content/integrations/embedding-models/google-gemini.md @@ -1,20 +1,17 @@ --- -title: "Google Generative AI" +id: google-gemini +name: "Google Gemini" --- -{% tabs group="code-lang" hideContent=true %} -{% tab label="Python" %} -{% /tab %} -{% tab label="Javascript" %} -{% /tab %} -{% /tabs %} +# Google Gemini Chroma provides a convenient wrapper around Google's Generative AI embedding API. This embedding function runs remotely on Google's servers, and requires an API key. You can get an API key by signing up for an account at [Google MakerSuite](https://makersuite.google.com/). -{% tabs group="code-lang" hideTabs=true %} -{% tab label="Python" %} +{% Tabs %} + +{% Tab label="python" %} This embedding function relies on the `google-generativeai` python package, which you can install with `pip install google-generativeai`. @@ -35,12 +32,13 @@ You can view a more [complete example](https://github.com/chroma-core/chroma/tre For more info - please visit the [official Google python docs](https://ai.google.dev/tutorials/python_quickstart). -{% /tab %} -{% tab label="Javascript" %} +{% /Tab %} + +{% Tab label="typescript" %} This embedding function relies on the `@google/generative-ai` npm package, which you can install with e.g. `npm install @google/generative-ai`. -```javascript +```typescript import { ChromaClient, GoogleGenerativeAiEmbeddingFunction } from "chromadb"; const embedder = new GoogleGenerativeAiEmbeddingFunction({ googleApiKey: "", @@ -64,5 +62,6 @@ You can view a more [complete example using Node](https://github.com/chroma-core For more info - please visit the [official Google JS docs](https://ai.google.dev/tutorials/node_quickstart). -{% /tab %} -{% /tabs %} +{% /Tab %} + +{% /Tabs %} diff --git a/docs/docs.trychroma.com/pages/integrations/hugging-face-server.md b/docs/docs.trychroma.com/markdoc/content/integrations/embedding-models/hugging-face-server.md similarity index 74% rename from docs/docs.trychroma.com/pages/integrations/hugging-face-server.md rename to docs/docs.trychroma.com/markdoc/content/integrations/embedding-models/hugging-face-server.md index e89b90fce26..beb40f4fcd7 100644 --- a/docs/docs.trychroma.com/pages/integrations/hugging-face-server.md +++ b/docs/docs.trychroma.com/markdoc/content/integrations/embedding-models/hugging-face-server.md @@ -1,13 +1,9 @@ --- -title: 'Hugging Face Text Embedding Server' +id: hugging-face-server +name: 'Hugging Face Server' --- -{% tabs group="code-lang" hideContent=true %} -{% tab label="Python" %} -{% /tab %} -{% tab label="Javascript" %} -{% /tab %} -{% /tabs %} +# Hugging Face Server Chroma provides a convenient wrapper for HuggingFace Text Embedding Server, a standalone server that provides text embeddings via a REST API. You can read more about it [**here**](https://github.com/huggingface/text-embeddings-inference). @@ -15,37 +11,37 @@ Chroma provides a convenient wrapper for HuggingFace Text Embedding Server, a st To run the embedding server locally you can run the following command from the root of the Chroma repository. The docker compose command will run Chroma and the embedding server together. -```bash +```terminal docker compose -f examples/server_side_embeddings/huggingface/docker-compose.yml up -d ``` or -```bash +```terminal docker run -p 8001:80 -d -rm --name huggingface-embedding-server ghcr.io/huggingface/text-embeddings-inference:cpu-0.3.0 --model-id BAAI/bge-small-en-v1.5 --revision -main ``` -{% note type="note" %} +{% Banner type="note" %} The above docker command will run the server with the `BAAI/bge-small-en-v1.5` model. You can find more information about running the server in docker [**here**](https://github.com/huggingface/text-embeddings-inference#docker). -{% /note %} +{% /Banner %} ## Usage -{% tabs group="code-lang" hideTabs=true %} -{% tab label="Python" %} +{% TabbedCodeBlock %} + +{% Tab label="python" %} ```python from chromadb.utils.embedding_functions import HuggingFaceEmbeddingServer huggingface_ef = HuggingFaceEmbeddingServer(url="http://localhost:8001/embed") ``` -The embedding model is configured on the server side. Check the docker-compose file in `examples/server_side_embeddings/huggingface/docker-compose.yml` for an example of how to configure the server. +{% /Tab %} -{% /tab %} -{% tab label="Javascript" %} +{% Tab label="typescript" %} -```javascript +```typescript import {HuggingFaceEmbeddingServerFunction} from 'chromadb'; const embedder = new HuggingFaceEmbeddingServerFunction({url:"http://localhost:8001/embed"}) @@ -53,9 +49,11 @@ const embedder = new HuggingFaceEmbeddingServerFunction({url:"http://localhost:8 const embeddings = embedder.generate(["document1","document2"]) // pass documents to query for .add and .query -const collection = await client.createCollection({name: "name", embeddingFunction: embedder}) -const collection = await client.getCollection({name: "name", embeddingFunction: embedder}) +let collection = await client.createCollection({name: "name", embeddingFunction: embedder}) +collection = await client.getCollection({name: "name", embeddingFunction: embedder}) ``` -{% /tab %} -{% /tabs %} +{% /Tab %} +{% /TabbedCodeBlock %} + +The embedding model is configured on the server side. Check the docker-compose file in `examples/server_side_embeddings/huggingface/docker-compose.yml` for an example of how to configure the server. diff --git a/docs/docs.trychroma.com/pages/integrations/hugging-face.md b/docs/docs.trychroma.com/markdoc/content/integrations/embedding-models/hugging-face.md similarity index 79% rename from docs/docs.trychroma.com/pages/integrations/hugging-face.md rename to docs/docs.trychroma.com/markdoc/content/integrations/embedding-models/hugging-face.md index 37e15581a2c..5a5cba53dbe 100644 --- a/docs/docs.trychroma.com/pages/integrations/hugging-face.md +++ b/docs/docs.trychroma.com/markdoc/content/integrations/embedding-models/hugging-face.md @@ -1,13 +1,9 @@ --- -title: Hugging Face +id: hugging-face +name: Hugging Face --- -{% tabs group="code-lang" hideContent=true %} -{% tab label="Python" %} -{% /tab %} -{% tab label="Javascript" %} -{% /tab %} -{% /tabs %} +# Hugging Face Chroma also provides a convenient wrapper around HuggingFace's embedding API. This embedding function runs remotely on HuggingFace's servers, and requires an API key. You can get an API key by signing up for an account at [HuggingFace](https://huggingface.co/). @@ -24,7 +20,3 @@ huggingface_ef = embedding_functions.HuggingFaceEmbeddingFunction( You can pass in an optional `model_name` argument, which lets you choose which HuggingFace model to use. By default, Chroma uses `sentence-transformers/all-MiniLM-L6-v2`. You can see a list of all available models [here](https://huggingface.co/models). -{% /tab %} -{% tab label="Javascript" %} -{% /tab %} -{% /tabs %} diff --git a/docs/docs.trychroma.com/pages/integrations/instructor.md b/docs/docs.trychroma.com/markdoc/content/integrations/embedding-models/instructor.md similarity index 96% rename from docs/docs.trychroma.com/pages/integrations/instructor.md rename to docs/docs.trychroma.com/markdoc/content/integrations/embedding-models/instructor.md index b24d0fc1610..2b6ebf3c282 100644 --- a/docs/docs.trychroma.com/pages/integrations/instructor.md +++ b/docs/docs.trychroma.com/markdoc/content/integrations/embedding-models/instructor.md @@ -1,7 +1,10 @@ --- -title: Instructor +id: instructor +name: Instructor --- +# Instructor + The [instructor-embeddings](https://github.com/HKUNLP/instructor-embedding) library is another option, especially when running on a machine with a cuda-capable GPU. They are a good local alternative to OpenAI (see the [Massive Text Embedding Benchmark](https://huggingface.co/blog/mteb) rankings). The embedding function requires the InstructorEmbedding package. To install it, run ```pip install InstructorEmbedding```. There are three models available. The default is `hkunlp/instructor-base`, and for better performance you can use `hkunlp/instructor-large` or `hkunlp/instructor-xl`. You can also specify whether to use `cpu` (default) or `cuda`. For example: diff --git a/docs/docs.trychroma.com/pages/integrations/jinaai.md b/docs/docs.trychroma.com/markdoc/content/integrations/embedding-models/jina-ai.md similarity index 77% rename from docs/docs.trychroma.com/pages/integrations/jinaai.md rename to docs/docs.trychroma.com/markdoc/content/integrations/embedding-models/jina-ai.md index cce47c7c81f..ac24c397aa9 100644 --- a/docs/docs.trychroma.com/pages/integrations/jinaai.md +++ b/docs/docs.trychroma.com/markdoc/content/integrations/embedding-models/jina-ai.md @@ -1,18 +1,15 @@ --- -title: Jina AI +id: jina-ai +name: Jina AI --- -{% tabs group="code-lang" hideContent=true %} -{% tab label="Python" %} -{% /tab %} -{% tab label="Javascript" %} -{% /tab %} -{% /tabs %} +# JinaAI Chroma provides a convenient wrapper around JinaAI's embedding API. This embedding function runs remotely on JinaAI's servers, and requires an API key. You can get an API key by signing up for an account at [JinaAI](https://jina.ai/embeddings/). -{% tabs group="code-lang" hideTabs=true %} -{% tab label="Python" %} +{% TabbedCodeBlock %} + +{% Tab label="python" %} ```python import chromadb.utils.embedding_functions as embedding_functions @@ -23,13 +20,13 @@ jinaai_ef = embedding_functions.JinaEmbeddingFunction( jinaai_ef(input=["This is my first text to embed", "This is my second document"]) ``` -You can pass in an optional `model_name` argument, which lets you choose which Jina model to use. By default, Chroma uses `jina-embedding-v2-base-en`. +{% /Tab %} -{% /tab %} -{% tab label="Javascript" %} +{% Tab label="typescript" %} + +```typescript +import { JinaEmbeddingFunction } from 'chromadb'; -```javascript -const {JinaEmbeddingFunction} = require('chromadb'); const embedder = new JinaEmbeddingFunction({ jinaai_api_key: 'jina_****', model_name: 'jina-embeddings-v2-base-en', @@ -42,5 +39,9 @@ const embeddings = embedder.generate(['document1', 'document2']); const collection = await client.createCollection({name: "name", embeddingFunction: embedder}) const collectionGet = await client.getCollection({name:"name", embeddingFunction: embedder}) ``` -{% /tab %} -{% /tabs %} + +{% /Tab %} + +{% /TabbedCodeBlock %} + +You can pass in an optional `model_name` argument, which lets you choose which Jina model to use. By default, Chroma uses `jina-embedding-v2-base-en`. diff --git a/docs/docs.trychroma.com/pages/integrations/ollama.md b/docs/docs.trychroma.com/markdoc/content/integrations/embedding-models/ollama.md similarity index 52% rename from docs/docs.trychroma.com/pages/integrations/ollama.md rename to docs/docs.trychroma.com/markdoc/content/integrations/embedding-models/ollama.md index 918ff2d06d5..1a00397f28f 100644 --- a/docs/docs.trychroma.com/pages/integrations/ollama.md +++ b/docs/docs.trychroma.com/markdoc/content/integrations/embedding-models/ollama.md @@ -1,14 +1,18 @@ --- -title: Ollama Embeddings +id: ollama +name: Ollama --- +# Ollama + Chroma provides a convenient wrapper around [Ollama](https://github.com/ollama/ollama)' s [embeddings API](https://github.com/ollama/ollama/blob/main/docs/api.md#generate-embeddings). You can use the `OllamaEmbeddingFunction` embedding function to generate embeddings for your documents with a [model](https://github.com/ollama/ollama?tab=readme-ov-file#model-library) of your choice. -{% tabs group="code-lang" %} -{% tab label="Python" %} +{% TabbedCodeBlock %} + +{% Tab label="python" %} ```python import chromadb.utils.embedding_functions as embedding_functions @@ -22,35 +26,12 @@ embeddings = ollama_ef(["This is my first text to embed", "This is my second document"]) ``` -{% /tab %} -{% tab label="Javascript" %} +{% /Tab %} -{% codetabs customHeader="js" %} -{% codetab label="ESM" %} -```js {% codetab=true %} -import {OllamaEmbeddingFunction} from "chromadb"; -const embedder = new OllamaEmbeddingFunction({ - url: "http://127.0.0.1:11434/api/embeddings", - model: "llama2" -}) - -// use directly -const embeddings = embedder.generate(["document1", "document2"]) +{% Tab label="typescript" %} -// pass documents to query for .add and .query -const collection = await client.createCollection({ - name: "name", - embeddingFunction: embedder -}) -const collection = await client.getCollection({ - name: "name", - embeddingFunction: embedder -}) -``` -{% /codetab %} -{% codetab label="CJS" %} -```js {% codetab=true %} -const {OllamaEmbeddingFunction} = require('chromadb'); +```typescript +import { OllamaEmbeddingFunction } from "chromadb"; const embedder = new OllamaEmbeddingFunction({ url: "http://127.0.0.1:11434/api/embeddings", model: "llama2" @@ -60,18 +41,16 @@ const embedder = new OllamaEmbeddingFunction({ const embeddings = embedder.generate(["document1", "document2"]) // pass documents to query for .add and .query -const collection = await client.createCollection({ +let collection = await client.createCollection({ name: "name", embeddingFunction: embedder }) -const collection = await client.getCollection({ +collection = await client.getCollection({ name: "name", embeddingFunction: embedder }) ``` -{% /codetab %} -{% /codetabs %} -{% /tab %} +{% /Tab %} -{% /tabs %} +{% /TabbedCodeBlock %} diff --git a/docs/docs.trychroma.com/pages/integrations/openai.md b/docs/docs.trychroma.com/markdoc/content/integrations/embedding-models/openai.md similarity index 80% rename from docs/docs.trychroma.com/pages/integrations/openai.md rename to docs/docs.trychroma.com/markdoc/content/integrations/embedding-models/openai.md index ee3adb8da0f..e119af989ac 100644 --- a/docs/docs.trychroma.com/pages/integrations/openai.md +++ b/docs/docs.trychroma.com/markdoc/content/integrations/embedding-models/openai.md @@ -1,13 +1,9 @@ --- -title: OpenAI +name: OpenAI +id: openai --- -{% tabs group="code-lang" hideContent=true %} -{% tab label="Python" %} -{% /tab %} -{% tab label="Javascript" %} -{% /tab %} -{% /tabs %} +# OpenAI Chroma provides a convenient wrapper around OpenAI's embedding API. This embedding function runs remotely on OpenAI's servers, and requires an API key. You can get an API key by signing up for an account at [OpenAI](https://openai.com/api/). @@ -17,12 +13,13 @@ The following OpenAI Embedding Models are supported: - `text-embedding-3-small` - `text-embedding-3-large` -{% note type="default" title="More Info" %} +{% Banner type="tip" %} Visit OpenAI Embeddings [documentation](https://platform.openai.com/docs/guides/embeddings) for more information. -{% /note %} +{% /Banner %} -{% tabs group="code-lang" hideTabs=true %} -{% tab label="Python" %} +{% Tabs %} + +{% Tab label="python" %} This embedding function relies on the `openai` python package, which you can install with `pip install openai`. @@ -48,13 +45,15 @@ openai_ef = embedding_functions.OpenAIEmbeddingFunction( ) ``` -{% /tab %} -{% tab label="Javascript" %} +{% /Tab %} + +{% Tab label="typescript" %} You can pass in an optional `model` argument, which lets you choose which OpenAI embeddings model to use. By default, Chroma uses `text-embedding-ada-002`. -```javascript -const {OpenAIEmbeddingFunction} = require('chromadb'); +```typescript +import { OpenAIEmbeddingFunction } from 'chromadb'; + const embeddingFunction = new OpenAIEmbeddingFunction({ openai_api_key: "apiKey", model: "text-embedding-3-small" @@ -64,15 +63,16 @@ const embeddingFunction = new OpenAIEmbeddingFunction({ const embeddings = embeddingFunction.generate(["document1","document2"]) // pass documents to query for .add and .query -const collection = await client.createCollection({ +let collection = await client.createCollection({ name: "name", embeddingFunction: embeddingFunction }) -const collection = await client.getCollection({ +collection = await client.getCollection({ name: "name", embeddingFunction: embeddingFunction }) ``` -{% /tab %} -{% /tabs %} +{% /Tab %} + +{% /Tabs %} diff --git a/docs/docs.trychroma.com/pages/integrations/roboflow.md b/docs/docs.trychroma.com/markdoc/content/integrations/embedding-models/roboflow.md similarity index 96% rename from docs/docs.trychroma.com/pages/integrations/roboflow.md rename to docs/docs.trychroma.com/markdoc/content/integrations/embedding-models/roboflow.md index 132efc5b3a6..9236fc476d8 100644 --- a/docs/docs.trychroma.com/pages/integrations/roboflow.md +++ b/docs/docs.trychroma.com/markdoc/content/integrations/embedding-models/roboflow.md @@ -1,7 +1,10 @@ --- -title: Roboflow +id: 'roboflow' +name: Roboflow --- +# Roboflow + You can use [Roboflow Inference](https://inference.roboflow.com) with Chroma to calculate multi-modal text and image embeddings with CLIP. through the `RoboflowEmbeddingFunction` class. Inference can be used through the Roboflow cloud, or run on your hardware. ## Roboflow Cloud Inference @@ -18,7 +21,7 @@ roboflow_ef = RoboflowEmbeddingFunction(api_key=API_KEY) Alternatively, you can set your API key as an environment variable: -```bash +```terminal export ROBOFLOW_API_KEY=YOUR_API_KEY ``` @@ -38,7 +41,7 @@ To install Inference, you will need Docker installed. Follow the [official Docke Then, you can install Inference with pip: -```bash +```terminal pip install inference inference-cli ``` @@ -46,7 +49,7 @@ With Inference installed, you can start an Inference server. This server will ru To start an Inference server, run: -```bash +```terminal inference server start ``` diff --git a/docs/docs.trychroma.com/pages/integrations/braintrust.md b/docs/docs.trychroma.com/markdoc/content/integrations/frameworks/braintrust.md similarity index 97% rename from docs/docs.trychroma.com/pages/integrations/braintrust.md rename to docs/docs.trychroma.com/markdoc/content/integrations/frameworks/braintrust.md index a64f54f95a8..3c846b5ff7a 100644 --- a/docs/docs.trychroma.com/pages/integrations/braintrust.md +++ b/docs/docs.trychroma.com/markdoc/content/integrations/frameworks/braintrust.md @@ -1,7 +1,10 @@ --- -title: Braintrust +id: braintrust +name: Braintrust --- +# Braintrust + [Braintrust](https://www.braintrustdata.com) is an enterprise-grade stack for building AI products including: evaluations, prompt playground, dataset management, tracing, etc. Braintrust provides a Typescript and Python library to run and log evaluations and integrates well with Chroma. diff --git a/docs/docs.trychroma.com/pages/integrations/haystack.md b/docs/docs.trychroma.com/markdoc/content/integrations/frameworks/haystack.md similarity index 98% rename from docs/docs.trychroma.com/pages/integrations/haystack.md rename to docs/docs.trychroma.com/markdoc/content/integrations/frameworks/haystack.md index 97ebe340fa5..04718db34fc 100644 --- a/docs/docs.trychroma.com/pages/integrations/haystack.md +++ b/docs/docs.trychroma.com/markdoc/content/integrations/frameworks/haystack.md @@ -1,7 +1,10 @@ --- -title: 💙 Haystack +id: haystack +name: Haystack --- +# Haystack + [Haystack](https://github.com/deepset-ai/haystack) is an open-source LLM framework in Python. It provides [embedders](https://docs.haystack.deepset.ai/v2.0/docs/embedders), [generators](https://docs.haystack.deepset.ai/v2.0/docs/generators) and [rankers](https://docs.haystack.deepset.ai/v2.0/docs/rankers) via a number of LLM providers, tooling for [preprocessing](https://docs.haystack.deepset.ai/v2.0/docs/preprocessors) and data preparation, connectors to a number of vector databases including Chroma and more. Haystack allows you to build custom LLM applications using both components readily available in Haystack and [custom components](https://docs.haystack.deepset.ai/v2.0/docs/custom-components). Some of the most common applications you can build with Haystack are retrieval-augmented generation pipelines (RAG), question-answering and semantic search. ![](https://img.shields.io/github/stars/deepset-ai/haystack.svg?style=social&label=Star&maxAge=2400) @@ -12,7 +15,7 @@ You can use Chroma together with Haystack by installing the integration and usin ### Installation -```bash +```terminal pip install chroma-haystack ``` diff --git a/docs/docs.trychroma.com/pages/integrations/langchain.md b/docs/docs.trychroma.com/markdoc/content/integrations/frameworks/langchain.md similarity index 96% rename from docs/docs.trychroma.com/pages/integrations/langchain.md rename to docs/docs.trychroma.com/markdoc/content/integrations/frameworks/langchain.md index 426683b13be..736ebfc9f87 100644 --- a/docs/docs.trychroma.com/pages/integrations/langchain.md +++ b/docs/docs.trychroma.com/markdoc/content/integrations/frameworks/langchain.md @@ -1,7 +1,10 @@ --- -title: 🦜️🔗 Langchain +id: langchain +name: Langchain --- +# Langchain + ## Langchain - Python - [LangChain + Chroma](https://blog.langchain.dev/langchain-chroma/) on the LangChain blog diff --git a/docs/docs.trychroma.com/markdoc/content/integrations/frameworks/llamaindex.md b/docs/docs.trychroma.com/markdoc/content/integrations/frameworks/llamaindex.md new file mode 100644 index 00000000000..529f838f31b --- /dev/null +++ b/docs/docs.trychroma.com/markdoc/content/integrations/frameworks/llamaindex.md @@ -0,0 +1,10 @@ +--- +id: llamaindex +name: LlamaIndex +--- + +# LlamaIndex + +- `LlamaIndex` [Vector Store page](https://docs.llamaindex.ai/en/stable/examples/vector_stores/ChromaIndexDemo.html) +- [Demo](https://github.com/jerryjliu/llama_index/blob/main/docs/examples/vector_stores/ChromaIndexDemo.ipynb) +- [Chroma Loader on Llamahub](https://llamahub.ai/l/chroma) diff --git a/docs/docs.trychroma.com/pages/integrations/openlit.md b/docs/docs.trychroma.com/markdoc/content/integrations/frameworks/openlit.md similarity index 94% rename from docs/docs.trychroma.com/pages/integrations/openlit.md rename to docs/docs.trychroma.com/markdoc/content/integrations/frameworks/openlit.md index 2d0d7e1aed9..3d493beee09 100644 --- a/docs/docs.trychroma.com/pages/integrations/openlit.md +++ b/docs/docs.trychroma.com/markdoc/content/integrations/frameworks/openlit.md @@ -1,13 +1,14 @@ --- -title: 🔍 OpenLIT +id: openlit +name: OpenLIT --- +# OpenLIT + [OpenLIT](https://github.com/openlit/openlit) is an OpenTelemetry-native LLM Application Observability tool and includes OpenTelemetry auto-instrumention for Chroma with just a single line of code helping you ensure your applications are monitored seamlessly, providing critical insights to improve performance, operations and reliability. For more information on how to use OpenLIT, see the [OpenLIT docs](https://docs.openlit.io/). -![OpenLIT Connections Banner](https://github.com/openlit/.github/blob/main/profile/assets/github-readme-connections-banner.png?raw=true) - ## Getting Started ### Step 1: Install OpenLIT diff --git a/docs/docs.trychroma.com/pages/integrations/openllmetry.md b/docs/docs.trychroma.com/markdoc/content/integrations/frameworks/openllmetry.md similarity index 91% rename from docs/docs.trychroma.com/pages/integrations/openllmetry.md rename to docs/docs.trychroma.com/markdoc/content/integrations/frameworks/openllmetry.md index e35ad6f81b0..cd4c5da3e76 100644 --- a/docs/docs.trychroma.com/pages/integrations/openllmetry.md +++ b/docs/docs.trychroma.com/markdoc/content/integrations/frameworks/openllmetry.md @@ -1,18 +1,21 @@ --- -title: 🔭 OpenLLMetry +id: openLLMetry +name: OpenLLMetry --- +# OpenLLMetry + [OpenLLMetry](https://www.traceloop.com/openllmetry) provides observability for systems using Chroma. It allows tracing calls to Chroma, OpenAI, and other services. It gives visibility to query and index calls as well as LLM prompts and completions. For more information on how to use OpenLLMetry, see the [OpenLLMetry docs](https://www.traceloop.com/docs/openllmetry). -![](/img/openllmetry.png) +![](/openllmetry.png) ### Example Install OpenLLMetry SDK by running: -```bash +```terminal pip install traceloop-sdk ``` diff --git a/docs/docs.trychroma.com/pages/integrations/streamlit.md b/docs/docs.trychroma.com/markdoc/content/integrations/frameworks/streamlit.md similarity index 98% rename from docs/docs.trychroma.com/pages/integrations/streamlit.md rename to docs/docs.trychroma.com/markdoc/content/integrations/frameworks/streamlit.md index 5db3ed55b56..30b2b60fea2 100644 --- a/docs/docs.trychroma.com/pages/integrations/streamlit.md +++ b/docs/docs.trychroma.com/markdoc/content/integrations/frameworks/streamlit.md @@ -1,7 +1,10 @@ --- -title: 🎈 Streamlit +id: streamlit +name: Streamlit --- +# Streamlit + Streamlit is an open-source Python library that makes it easy to create and share beautiful, custom web apps for machine learning and data science. In just a few minutes you can build and deploy powerful data apps. ![](https://img.shields.io/github/stars/streamlit/streamlit.svg?style=social&label=Star&maxAge=2400) diff --git a/docs/docs.trychroma.com/pages/deployment/auth.md b/docs/docs.trychroma.com/markdoc/content/production/administration/auth.md similarity index 87% rename from docs/docs.trychroma.com/pages/deployment/auth.md rename to docs/docs.trychroma.com/markdoc/content/production/administration/auth.md index 1605b0eee22..07d1b31ab2d 100644 --- a/docs/docs.trychroma.com/pages/deployment/auth.md +++ b/docs/docs.trychroma.com/markdoc/content/production/administration/auth.md @@ -1,23 +1,9 @@ ---- -title: 🔒 Auth ---- - -{% tabs group="code-lang" hideContent=true %} - -{% tab label="Python" %} -{% /tab %} - -{% tab label="Javascript" %} -{% /tab %} - -{% /tabs %} +# Auth You can configure Chroma to use authentication when in server/client mode only. Supported authentication methods: -{% special_table %} -{% /special_table %} | Authentication Method | Basic Auth (Pre-emptive) | Static API Token | | --------------------- | ------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | @@ -31,15 +17,15 @@ Supported authentication methods: In this guide we will add authentication to a simple Chroma server running locally using our CLI: -```shell +```terminal chroma run --path ``` We also have dedicated auth guides for various deployments: -* [Docker](/deployment/docker#authentication-with-docker) -* [AWS](/deployment/aws#authentication-with-AWS) -* [GCP](/deployment/gcp#authentication-with-GCP) -* [Azure](/deployment/azure#authentication-with-Azure) +* [Docker](../containers/docker#authentication-with-docker) +* [AWS](../cloud-providers/aws#authentication-with-AWS) +* [GCP](../cloud-providers/gcp#authentication-with-GCP) +* [Azure](../cloud-providers/azure#authentication-with-Azure) ### Encrypted User:Password Authentication @@ -47,13 +33,17 @@ We also have dedicated auth guides for various deployments: ##### Generate Server-Side Credentials -{% note type="note" title="Security Practices" %} +{% Banner type="note" %} + +**Security Practices** + A good security practice is to store the password securely. In the example below we use [bcrypt](https://en.wikipedia.org/wiki/Bcrypt) (currently the only supported hash in Chroma server side auth) to hash the plaintext password. If you'd like to see support for additional hash functions, feel free to [contribute](../contributing) new ones! -{% /note %} + +{% /Banner %} To generate the password hash, run the following command (you may need to install `httpasswd`): -```bash +```terminal htpasswd -Bbn admin admin > server.htpasswd ``` @@ -63,21 +53,22 @@ This creates the bcrypt password hash for the password `admin`, for the `admin` Set the following environment variables: -```bash +```terminal export CHROMA_SERVER_AUTHN_CREDENTIALS_FILE="" export CHROMA_SERVER_AUTHN_PROVIDER="chromadb.auth.basic_authn.BasicAuthenticationServerProvider" ``` And run the Chroma server: -```bash +```terminal chroma run --path ``` #### Client Set-Up -{% tabs group="code-lang" hideTabs=true %} -{% tab label="Python" %} +{% Tabs %} + +{% Tab label="python" %} We will use Chroma's `Settings` object to define the authentication method on the client. @@ -97,10 +88,11 @@ client = chromadb.HttpClient( chroma_client.heartbeat() ``` -{% /tab %} -{% tab label="Javascript" %} +{% /Tab %} -```javascript +{% Tab label="typescript" %} + +```typescript import { ChromaClient } from "chromadb"; const chromaClient = new ChromaClient({ @@ -114,8 +106,9 @@ const chromaClient = new ChromaClient({ chromaClient.heartbeat() ``` -{% /tab %} -{% /tabs %} +{% /Tab %} + +{% /Tabs %} We recommend setting the environment variable `CHROMA_CLIENT_AUTH_CREDENTIALS` instead of specifying the credentials in code. @@ -123,20 +116,24 @@ We recommend setting the environment variable `CHROMA_CLIENT_AUTH_CREDENTIALS` i #### Server Set-Up -{% note type="note" title="Security Note" %} +{% Banner type="note" %} + +**Security Note** + Current implementation of static API token auth supports only ENV based tokens. Tokens must be alphanumeric ASCII strings. Tokens are case-sensitive. -{% /note %} + +{% /Banner %} If, for example, you want the static API token to be "test-token", set the following environment variables. This will set `Authorization: Bearer test-token` as your authentication header. -```bash +```terminal export CHROMA_SERVER_AUTHN_CREDENTIALS="test-token" export CHROMA_SERVER_AUTHN_PROVIDER="chromadb.auth.token_authn.TokenAuthenticationServerProvider" ``` To use `X-Chroma-Token: test-token` type of authentication header you can set the `CHROMA_AUTH_TOKEN_TRANSPORT_HEADER` environment variable: -```bash +```terminal export CHROMA_SERVER_AUTHN_CREDENTIALS="test-token" export CHROMA_SERVER_AUTHN_PROVIDER="chromadb.auth.token_authn.TokenAuthenticationServerProvider" export CHROMA_AUTH_TOKEN_TRANSPORT_HEADER="X-Chroma-Token" @@ -144,13 +141,13 @@ export CHROMA_AUTH_TOKEN_TRANSPORT_HEADER="X-Chroma-Token" Then, run the Chroma server: -```bash +```terminal chroma run --path ``` To configure multiple tokens and use them for role-based access control (RBAC), use a file like [this](https://github.com/chroma-core/chroma/blob/main/examples/basic_functionality/authz/authz.yaml) and the following environment variables: -```bash +```terminal export CHROMA_SERVER_AUTHN_CREDENTIALS_FILE="" export CHROMA_SERVER_AUTHZ_CONFIG_FILE="" # Note: these are the same! export CHROMA_SERVER_AUTHN_PROVIDER="chromadb.auth.token_authn.TokenAuthenticationServerProvider" @@ -159,8 +156,9 @@ export CHROMA_SERVER_AUTHZ_PROVIDER="chromadb.auth.simple_rbac_authz.SimpleRBACA #### Client Set-Up -{% tabs group="code-lang" hideTabs=true %} -{% tab label="Python" %} +{% Tabs %} + +{% Tab label="python" %} We will use Chroma's `Settings` object to define the authentication method on the client. @@ -186,10 +184,11 @@ If you are using a custom `CHROMA_AUTH_TOKEN_TRANSPORT_HEADER` (like `X-Chroma-T chroma_auth_token_transport_header="X-Chroma-Token" ``` -{% /tab %} -{% tab label="Javascript" %} +{% /Tab %} + +{% Tab label="typescript" %} -```javascript +```typescript import { ChromaClient } from "chromadb"; const chromaClient = new ChromaClient({ @@ -204,7 +203,7 @@ const chromaClient = new ChromaClient({ chromaClient.heartbeat() ``` -{% /tab %} -{% /tabs %} +{% /Tab %} +{% /Tabs %} -We recommend setting the environment variable `CHROMA_CLIENT_AUTH_CREDENTIALS` instead of specifying the token in code. Similarly, you can read the value of `CHROMA_AUTH_TOKEN_TRANSPORT_HEADER` in the client construction. +We recommend setting the environment variable `CHROMA_CLIENT_AUTH_CREDENTIALS` instead of specifying the token in code. Similarly, you can read the value of `CHROMA_AUTH_TOKEN_TRANSPORT_HEADER` in the client construction. \ No newline at end of file diff --git a/docs/docs.trychroma.com/pages/deployment/migration.md b/docs/docs.trychroma.com/markdoc/content/production/administration/migration.md similarity index 88% rename from docs/docs.trychroma.com/pages/deployment/migration.md rename to docs/docs.trychroma.com/markdoc/content/production/administration/migration.md index 4f94c68684e..4dfb835d13e 100644 --- a/docs/docs.trychroma.com/pages/deployment/migration.md +++ b/docs/docs.trychroma.com/markdoc/content/production/administration/migration.md @@ -1,6 +1,4 @@ ---- -title: "✈️ Migration" ---- +# Migration Schema and data format changes are a necessary evil of evolving software. We take changes seriously and make them infrequently and only when necessary. @@ -20,14 +18,6 @@ We will aim to provide: ## Migration Log -### v0.6.0 - -`list_collections` now returns a list of collection *names*, instead of collection objects. - -Previously, `list_collections` returned a list of collection objects, configured with the default embedding function. If one of your collections was created with a different embedding function, using the version returned by `list_collections` would result in various errors. - -We are working on embedding function persistence to allow you to configure a collection with an embedding function once, and not have to specify it again (in `get_collection` for example). - ### v0.5.17 We no longer support sending empty lists or dictionaries for metadata filtering, ID filtering, etc. For example, @@ -198,22 +188,22 @@ CHROMA_AUTH_TOKEN_TRANSPORT_HEADER="AUTHORIZATION" #### Reference of changed configuration values - Overall config - - `chroma_client_auth_token_transport_header`: renamed to `chroma_auth_token_transport_header`. - - `chroma_server_auth_token_transport_header`: renamed to `chroma_auth_token_transport_header`. + - `chroma_client_auth_token_transport_header`: renamed to `chroma_auth_token_transport_header`. + - `chroma_server_auth_token_transport_header`: renamed to `chroma_auth_token_transport_header`. - Client config - - `chroma_client_auth_credentials_provider`: deleted. Functionality is now in `chroma_client_auth_provider`. - - `chroma_client_auth_protocol_adapter`: deleted. Functionality is now in `chroma_client_auth_provider`. - - `chroma_client_auth_credentials_file`: deleted. Functionality is now in `chroma_client_auth_credentials`. - - These changes also apply to the Typescript client. + - `chroma_client_auth_credentials_provider`: deleted. Functionality is now in `chroma_client_auth_provider`. + - `chroma_client_auth_protocol_adapter`: deleted. Functionality is now in `chroma_client_auth_provider`. + - `chroma_client_auth_credentials_file`: deleted. Functionality is now in `chroma_client_auth_credentials`. + - These changes also apply to the Typescript client. - Server authn - - `chroma_server_auth_provider`: Renamed to `chroma_server_authn_provider`. - - `chroma_server_auth_configuration_provider`: deleted. Functionality is now in `chroma_server_authn_provider`. - - `chroma_server_auth_credentials_provider`: deleted. Functionality is now in `chroma_server_authn_provider`. - - `chroma_server_auth_credentials_file`: renamed to `chroma_server_authn_credentials_file`. - - `chroma_server_auth_credentials`: renamed to `chroma_server_authn_credentials`. - - `chroma_server_auth_configuration_file`: renamed to `chroma_server_authn_configuration_file`. + - `chroma_server_auth_provider`: Renamed to `chroma_server_authn_provider`. + - `chroma_server_auth_configuration_provider`: deleted. Functionality is now in `chroma_server_authn_provider`. + - `chroma_server_auth_credentials_provider`: deleted. Functionality is now in `chroma_server_authn_provider`. + - `chroma_server_auth_credentials_file`: renamed to `chroma_server_authn_credentials_file`. + - `chroma_server_auth_credentials`: renamed to `chroma_server_authn_credentials`. + - `chroma_server_auth_configuration_file`: renamed to `chroma_server_authn_configuration_file`. - Server authz - - `chroma_server_authz_ignore_paths`: deleted. Functionality is now in `chroma_server_auth_ignore_paths`. + - `chroma_server_authz_ignore_paths`: deleted. Functionality is now in `chroma_server_auth_ignore_paths`. To see the full changes, you can read the [PR](https://github.com/chroma-core/chroma/pull/1970/files) or reach out to the Chroma team on [Discord](https://discord.gg/MMeYNTmh3x). @@ -321,12 +311,12 @@ If you upgrade to `0.4.0` and try to access data stored in the old way, you will Here is how to install and use the CLI: -``` +```terminal pip install chroma-migrate chroma-migrate ``` -![](/img/chroma-migrate.png) +![](/chroma-migrate.png) If you need any help with this migration, please reach out! We are on [Discord](https://discord.com/channels/1073293645303795742/1129286514845691975) ready to help. @@ -340,4 +330,4 @@ If you need any help with this migration, please reach out! We are on [Discord]( import chromadb from chromadb.config import Settings client = chromadb.PersistentClient(path="./path/to/chroma", settings=Settings(allow_reset=True)) -``` +``` \ No newline at end of file diff --git a/docs/docs.trychroma.com/pages/deployment/observability.md b/docs/docs.trychroma.com/markdoc/content/production/administration/observability.md similarity index 63% rename from docs/docs.trychroma.com/pages/deployment/observability.md rename to docs/docs.trychroma.com/markdoc/content/production/administration/observability.md index 40bb435bf63..fac6ff43f96 100644 --- a/docs/docs.trychroma.com/pages/deployment/observability.md +++ b/docs/docs.trychroma.com/markdoc/content/production/administration/observability.md @@ -1,13 +1,12 @@ ---- -title: "👀 Observability" ---- +# Observability + ## Backend Observability Chroma is instrumented with [OpenTelemetry](https://opentelemetry.io/) hooks for observability. {% note type="default" title="Telemetry vs Observability" %} -"[Telemetry](/telemetry)" refers to anonymous product usage statistics we collect. "Observability" refers to metrics, logging, and tracing which can be used by anyone operating a Chroma deployment. Observability features listed on this page are **never** sent back to Chroma; they are for end-users to better understand how their Chroma deployment is behaving. +"[Telemetry](../../docs/overview/telemetry)" refers to anonymous product usage statistics we collect. "Observability" refers to metrics, logging, and tracing which can be used by anyone operating a Chroma deployment. Observability features listed on this page are **never** sent back to Chroma; they are for end-users to better understand how their Chroma deployment is behaving. {% /note %} ### Available Observability @@ -24,13 +23,13 @@ Tracing is configured with four environment variables: - `CHROMA_OTEL_GRANULARITY`: A value from the [OpenTelemetryGranularity enum](https://github.com/chroma-core/chroma/tree/main/chromadb/telemetry/opentelemetry/__init__.py). Specifies how detailed tracing should be. We also have dedicated observability guides for various deployments: -* [Docker](/deployment/docker#observability-with-docker) -* [AWS](/deployment/aws#observability-with-AWS) -* [GCP](/deployment/gcp#observability-with-GCP) -* [Azure](/deployment/azure#observability-with-Azure) +* [Docker](../containers/docker#observability-with-docker) +* [AWS](../cloud-providers/aws#observability-with-AWS) +* [GCP](../cloud-providers/gcp#observability-with-GCP) +* [Azure](../cloud-providers/azure#observability-with-Azure) ## Client (SDK) Observability Several observability platforms offer built-in integrations for Chroma, allowing you to monitor your application's interactions with the Chroma server: -- [OpenLLMetry Integration](/integrations/openllmetry). -- [OpenLIT Integration](/integrations/openlit). +- [OpenLLMetry Integration](../../integrations/frameworks/openllmetry). +- [OpenLIT Integration](../../integrations/frameworks/openlit). \ No newline at end of file diff --git a/docs/docs.trychroma.com/pages/deployment/performance.md b/docs/docs.trychroma.com/markdoc/content/production/administration/performance.md similarity index 96% rename from docs/docs.trychroma.com/pages/deployment/performance.md rename to docs/docs.trychroma.com/markdoc/content/production/administration/performance.md index 2b0c28e27c9..c617b03570e 100644 --- a/docs/docs.trychroma.com/pages/deployment/performance.md +++ b/docs/docs.trychroma.com/markdoc/content/production/administration/performance.md @@ -1,6 +1,5 @@ ---- -title: "Single-Node Chroma: Performance and Limitations" ---- +# Single-Node Chroma: Performance and Limitations + The single-node version of Chroma is designed to be easy to deploy and maintain, while still providing robust performance that satisfies a broad range of production applications. @@ -16,9 +15,6 @@ Roughly speaking, here is the sort of performance you can expect from Chroma on - Small documents (100-200 words) - Three metadata fields per record. -{% special_table %} -{% /special_table %} - | Instance Type | System RAM | Approx. Max Collection Size | Mean Latency (insert) | 99.9% Latency (insert) | Mean Latency (query) | 99.9% Latency (query) | Monthly Cost | |-----------------|------------|-----------------------------|-----------------------|------------------------|----------------------|-----------------------|--------------| | **t3.small** | 2 | 250,000 | 55ms | 250ms | 22ms | 72ms | $15.936 | @@ -68,11 +64,11 @@ As collections get larger and the size of the index grows, inserts and queries b ### Query Latency -![query-latency](/img/query-latency.png) +![query-latency](/query-latency.png) ### Insert Latency -![insert-latency](/img/insert-latency.png) +![insert-latency](/insert-latency.png) {% note type="tip" title="" %} If you’re using multiple collections, performance looks quite similar, based on the total number of embeddings across collections. Splitting collections into multiple smaller collections doesn’t help, but it doesn’t hurt, either, as long as they all fit in memory at once. @@ -86,9 +82,9 @@ This means that under concurrent load, the average latency of each request will When writing, the increased latency is more pronounced with larger batch sizes, as the system is more completely saturated. We have experimentally verified this: as the number of concurrent writers is increased, average latency increases linearly. -![concurrent-writes](/img/concurrent-writes.png) +![concurrent-writes](/concurrent-writes.png) -![concurrent-queries](/img/concurrent-queries.png) +![concurrent-queries](/concurrent-queries.png) Despite the effect on latency, Chroma does remain stable with high concurrent load. Too many concurrent users can eventually increase latency to the point where the system does not perform acceptably, but this typically only happens with larger batch sizes. As the above graphs shows, the system remains usable with dozens to hundreds of operations per second. @@ -100,7 +96,7 @@ As a CPU bound application, it’s not surprising that CPU speed and type makes As the data demonstrates, although it is not fully parallelized, Chroma can still take some advantage of multiple CPU cores for better throughput. -![cpu-mean-query-latency](/img/cpu-mean-query-latency.png) +![cpu-mean-query-latency](/cpu-mean-query-latency.png) {% note type="tip" title="" %} Note the slightly increased latency for the t3.2xlarge instance. Logically, it should be faster than the other t3 series instances, since it has the same class of CPU, and more of them. @@ -120,7 +116,7 @@ The second factor to consider is the batch size of each request. Performance is Experimentation confirms this: overall throughput (total number of embeddings inserted, across batch size and request count) remains fairly flat between batch sizes of 100-500: -![concurrent-inserts](/img/concurrent-inserts.png) +![concurrent-inserts](/concurrent-inserts.png) Given that smaller batches have lower, more consistent latency and are less likely to lead to timeout errors, we recommend batches on the smaller side of this curve: anything between 50 and 250 is a reasonable choice. @@ -128,4 +124,4 @@ Given that smaller batches have lower, more consistent latency and are less like Users should feel comfortable relying on Chroma for use cases approaching tens of millions of embeddings, when deployed on the right hardware. It’s average and upper-bound latency for both reads and writes make it a good platform for all but the largest AI-based applications, supporting potentially thousands of simultaneous human users (depending on your application’s backend access patterns.) -As a single-node solution, though, it won’t scale forever. If you find your needs exceeding the parameters laid out in this analysis, we are extremely interested in hearing from you. Please fill out [this form](https://airtable.com/appqd02UuQXCK5AuY/pagr1D0NFQoNpUpNZ/form), and we will add you to a dedicated Slack workspace for supporting production users. We would love to help you think through the design of your system, whether Chroma has a place in it, or if you would be a good fit for our upcoming distributed cloud service. +As a single-node solution, though, it won’t scale forever. If you find your needs exceeding the parameters laid out in this analysis, we are extremely interested in hearing from you. Please fill out [this form](https://airtable.com/appqd02UuQXCK5AuY/pagr1D0NFQoNpUpNZ/form), and we will add you to a dedicated Slack workspace for supporting production users. We would love to help you think through the design of your system, whether Chroma has a place in it, or if you would be a good fit for our upcoming distributed cloud service. \ No newline at end of file diff --git a/docs/docs.trychroma.com/pages/deployment/client-server-mode.md b/docs/docs.trychroma.com/markdoc/content/production/chroma-server/client-server-mode.md similarity index 68% rename from docs/docs.trychroma.com/pages/deployment/client-server-mode.md rename to docs/docs.trychroma.com/markdoc/content/production/chroma-server/client-server-mode.md index 3d5c48e47fa..f4bab933f81 100644 --- a/docs/docs.trychroma.com/pages/deployment/client-server-mode.md +++ b/docs/docs.trychroma.com/markdoc/content/production/chroma-server/client-server-mode.md @@ -1,31 +1,20 @@ ---- -title: "Running Chroma in Client-Server Mode" ---- - -{% tabs group="code-lang" hideContent=true %} - -{% tab label="Python" %} -{% /tab %} - -{% tab label="Javascript" %} -{% /tab %} - -{% /tabs %} +# Running Chroma in Client-Server Mode Chroma can also be configured to run in client/server mode. In this mode, the Chroma client connects to a Chroma server running in a separate process. -This means that you can deploy single-node Chroma to a [Docker container](./docker), or a machine hosted by a cloud provider like [AWS](./aws), GCP, Azure, and others. Then, you can access your Chroma server from your application using our `HttpClient`. +This means that you can deploy single-node Chroma to a [Docker container](../containers/docker), or a machine hosted by a cloud provider like [AWS](../cloud-providers/aws), [GCP](../cloud-providers/gcp), [Azure](../cloud-providers/azure), and others. Then, you can access your Chroma server from your application using our `HttpClient` (or `ChromaClient` for JS/TS users). You can quickly experiment locally with Chroma in client/server mode by using our CLI: -```shell +```terminal chroma run --path /db_path ``` -Then use the Chroma `HttpClient` to connect to the server: +{% Tabs %} -{% tabs group="code-lang" hideTabs=true %} -{% tab label="Python" %} +{% Tab label="python" %} + +Then use the Chroma `HttpClient` to connect to the server: ```python import chromadb @@ -51,17 +40,21 @@ asyncio.run(main()) If you intend to deploy your Chroma server, you may want to consider our [thin-client package](./thin-client) for client-side interactions. -{% /tab %} +{% /Tab %} + +{% Tab label="typescript" %} -{% tabs group="code-lang" hideTabs=true %} -{% tab label="Javascript" %} +Then instantiate a new `ChromaClient`. The default is to connect to a Chroma server running on localhost. -```javascript +```typescript // CJS const { ChromaClient } = require("chromadb"); // ESM import { ChromaClient } from "chromadb"; + const client = new ChromaClient(); ``` -{% /tab %} +{% /Tab %} + +{% /Tabs %} \ No newline at end of file diff --git a/docs/docs.trychroma.com/pages/deployment/thin-client.md b/docs/docs.trychroma.com/markdoc/content/production/chroma-server/python-thin-client.md similarity index 93% rename from docs/docs.trychroma.com/pages/deployment/thin-client.md rename to docs/docs.trychroma.com/markdoc/content/production/chroma-server/python-thin-client.md index 47e8a6b7f8a..ea276842ed4 100644 --- a/docs/docs.trychroma.com/pages/deployment/thin-client.md +++ b/docs/docs.trychroma.com/markdoc/content/production/chroma-server/python-thin-client.md @@ -1,6 +1,5 @@ ---- -title: "Chroma's Thin-Client" ---- +# Chroma's Thin-Client + If you are running Chroma in client-server mode in a Python application, you may not need the full Chroma Python library. Instead, you can use the lightweight client-only library. In this case, you can install the `chromadb-client` package **instead** of our `chromadb` package. @@ -8,7 +7,7 @@ In this case, you can install the `chromadb-client` package **instead** of our ` The `chromadb-client` package is a lightweight HTTP client for the server with a minimal dependency footprint. -```python +```terminal pip install chromadb-client ``` @@ -24,4 +23,4 @@ async def main(): Note that the `chromadb-client` package is a subset of the full Chroma library and does not include all the dependencies. If you want to use the full Chroma library, you can install the `chromadb` package instead. -Most importantly, the thin-client package has no default embedding functions. If you `add()` documents without embeddings, you must have manually specified an embedding function and installed the dependencies for it. +Most importantly, the thin-client package has no default embedding functions. If you `add()` documents without embeddings, you must have manually specified an embedding function and installed the dependencies for it. \ No newline at end of file diff --git a/docs/docs.trychroma.com/pages/deployment/aws.md b/docs/docs.trychroma.com/markdoc/content/production/cloud-providers/aws.md similarity index 91% rename from docs/docs.trychroma.com/pages/deployment/aws.md rename to docs/docs.trychroma.com/markdoc/content/production/cloud-providers/aws.md index ab73e22c84e..33ba16d1109 100644 --- a/docs/docs.trychroma.com/pages/deployment/aws.md +++ b/docs/docs.trychroma.com/markdoc/content/production/cloud-providers/aws.md @@ -1,25 +1,17 @@ ---- -title: "☁️ AWS Deployment" ---- +# AWS Deployment -{% tabs group="code-lang" hideContent=true %} +{% Banner type="tip" %} -{% tab label="Python" %} -{% /tab %} +**Hosted Chroma** -{% tab label="Javascript" %} -{% /tab %} - -{% /tabs %} - -{% note type="tip" title="Hosted Chroma" %} Chroma Cloud, our fully managed hosted service, is in early access. Fill out the survey to jump the waitlist and get the best retrieval experience. Full access coming Q1 2025. [📝 30 second survey](https://airtable.com/shrOAiDUtS2ILy5vZ) -{% /note %} +{% /Banner %} + +{% Banner type="tip" %} -{% note type="tip" title="" %} If you are using Chroma in production, please fill out [this form](https://airtable.com/appqd02UuQXCK5AuY/pagr1D0NFQoNpUpNZ/form), and we will add you to a dedicated Slack workspace for supporting production users. This is the best place to @@ -28,7 +20,8 @@ This is the best place to 3. Get swag! We would love to help you think through the design of your system, or if you would be a good fit for our upcoming distributed cloud service. -{% /note %} + +{% /Banner %} ## A Simple AWS Deployment @@ -39,30 +32,36 @@ There are many possible configurations, but for convenience we have provided a very simple AWS CloudFormation template to experiment with deploying Chroma to EC2 on AWS. -{% note type="warning" title="" %} +{% Banner type="warn" %} + Chroma and its underlying database [need at least 2GB of RAM](./performance#results-summary), which means it won't fit on the 1gb instances provided as part of the AWS Free Tier. This template uses a [`t3.small`](https://aws.amazon.com/ec2/instance-types/t3/#Product%20Details) EC2 instance, which costs about two cents an hour, or $15 for a full month, and gives you 2GiB of memory. If you follow these instructions, AWS will bill you accordingly. -{% /note %} -{% note type="warning" title="" %} +{% /Banner %} + +{% Banner type="warn" %} + In this guide we show you how to secure your endpoint using [Chroma's native authentication support](./aws#authentication-with-aws). Alternatively, you can put it behind [AWS API Gateway](https://aws.amazon.com/api-gateway/) or add your own authenticating proxy. This basic stack doesn't support any kind of authentication; anyone who knows your server IP will be able to add and query for embeddings. -{% /note %} -{% note type="warning" title="" %} +{% /Banner %} + +{% Banner type="warn" %} + By default, this template saves all data on a single volume. When you delete or replace it, the data will disappear. For serious production use (with high availability, backups, etc.) please read and understand the CloudFormation template and use it as a basis for what you need, or reach out to the Chroma team for assistance. -{% /note %} + +{% /Banner %} ### Step 1: Get an AWS Account @@ -81,7 +80,7 @@ and will be using environment variables to configure AWS. Export the `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` environment variables in your shell: -```shell +```terminal export AWS_ACCESS_KEY_ID=**\*\***\*\*\*\***\*\*** export AWS_SECRET_ACCESS_KEY=****\*\*****\*\*****\*\***** ``` @@ -89,7 +88,7 @@ export AWS_SECRET_ACCESS_KEY=****\*\*****\*\*****\*\***** You can also configure AWS to use a region of your choice using the `AWS_REGION` environment variable: -```shell +```terminal export AWS_REGION=us-east-1 ``` @@ -101,14 +100,14 @@ To launch the template using AWS CloudFormation, run the following command line Replace `--stack-name my-chroma-stack` with a different stack name, if you wish. -```sh +```terminal aws cloudformation create-stack --stack-name my-chroma-stack --template-url https://s3.amazonaws.com/public.trychroma.com/cloudformation/latest/chroma.cf.json ``` Wait a few minutes for the server to boot up, and Chroma will be available! You can get the public IP address of your new Chroma server using the AWS console, or using the following command: -```sh +```terminal aws cloudformation describe-stacks --stack-name my-chroma-stack --query 'Stacks[0].Outputs' ``` @@ -131,7 +130,7 @@ above, but on a `m5.4xlarge` EC2 instance, and adding a KeyPair named `mykey` so anyone with the associated private key can SSH into the machine: -```shell +```terminal aws cloudformation create-stack --stack-name my-chroma-stack --template-url https://s3.amazonaws.com/public.trychroma.com/cloudformation/latest/chroma.cf.json \ --parameters ParameterKey=KeyName,ParameterValue=mykey \ ParameterKey=InstanceType,ParameterValue=m5.4xlarge @@ -141,10 +140,11 @@ aws cloudformation create-stack --stack-name my-chroma-stack --template-url http Once your EC2 instance is up and running with Chroma, all you need to do is configure your `HttpClient` to use the server's IP address and port -`8000`. Since you are running a Chroma server on AWS, our [thin-client package](./thin-client.md) may be enough for your application. +`8000`. Since you are running a Chroma server on AWS, our [thin-client package](../chroma-server/python-thin-client) may be enough for your application. + +{% TabbedCodeBlock %} -{% tabs group="code-lang" hideTabs=true %} -{% tab label="Python" %} +{% Tab label="python" %} ```python import chromadb @@ -156,10 +156,11 @@ chroma_client = chromadb.HttpClient( chroma_client.heartbeat() ``` -{% /tab %} -{% tab label="Javascript" %} +{% /Tab %} -```javascript +{% Tab label="typescript" %} + +```typescript import { ChromaClient } from "chromadb"; const chromaClient = new ChromaClient({ @@ -169,8 +170,9 @@ const chromaClient = new ChromaClient({ chromaClient.heartbeat() ``` -{% /tab %} -{% /tabs %} +{% /Tab %} + +{% /TabbedCodeBlock %} ### Step 5: Clean Up (optional). @@ -181,7 +183,7 @@ This will destroy all the data in your Chroma database, unless you've taken a snapshot or otherwise backed it up. {% /note %} -```shell +```terminal aws cloudformation delete-stack --stack-name my-chroma-stack ``` @@ -189,19 +191,23 @@ aws cloudformation delete-stack --stack-name my-chroma-stack By default, the EC2 instance created by our CloudFormation template will run with no authentication. There are many ways to secure your Chroma instance on AWS. In this guide we will use a simple set-up using Chroma's native authentication support. -You can learn more about authentication with Chroma in the [Auth Guide](/deployment/auth). +You can learn more about authentication with Chroma in the [Auth Guide](../administration/auth). ### Static API Token Authentication #### Customize Chroma's CloudFormation Stack -{% note type="note" title="Security Note" %} +{% Banner type="note" %} + +**Security Note** + Current implementation of static API token auth supports only ENV based tokens. Tokens must be alphanumeric ASCII strings. Tokens are case-sensitive. -{% /note %} + +{% /Banner %} If, for example, you want the static API token to be "test-token", pass the following parameters when creating your Chroma stack. This will set `Authorization: Bearer test-token` as your authentication header. -```shell +```terminal aws cloudformation create-stack --stack-name my-chroma-stack --template-url https://s3.amazonaws.com/public.trychroma.com/cloudformation/latest/chroma.cf.json \ --parameters ParameterKey=ChromaServerAuthCredentials,ParameterValue="test-token" \ ParameterKey=ChromaServerAuthProvider,ParameterValue="chromadb.auth.token_authn.TokenAuthenticationServerProvider" @@ -209,7 +215,7 @@ aws cloudformation create-stack --stack-name my-chroma-stack --template-url http To use `X-Chroma-Token: test-token` type of authentication header you can set the `ChromaAuthTokenTransportHeader` parameter: -```shell +```terminal aws cloudformation create-stack --stack-name my-chroma-stack --template-url https://s3.amazonaws.com/public.trychroma.com/cloudformation/latest/chroma.cf.json \ --parameters ParameterKey=ChromaServerAuthCredentials,ParameterValue="test-token" \ ParameterKey=ChromaServerAuthProvider,ParameterValue="chromadb.auth.token_authn.TokenAuthenticationServerProvider" \ @@ -220,12 +226,13 @@ aws cloudformation create-stack --stack-name my-chroma-stack --template-url http Add the `CHROMA_CLIENT_AUTH_CREDENTIALS` environment variable to your local environment, and set it to the token you provided the server (`test-token` in this example): -```shell +```terminal export CHROMA_CLIENT_AUTH_CREDENTIALS="test-token" ``` -{% tabs group="code-lang" hideTabs=true %} -{% tab label="Python" %} +{% Tabs %} + +{% Tab label="python" %} We will use Chroma's `Settings` object to define the authentication method on the client. @@ -255,10 +262,11 @@ If you are using a custom `CHROMA_AUTH_TOKEN_TRANSPORT_HEADER` (like `X-Chroma-T chroma_auth_token_transport_header=os.getenv("CHROMA_AUTH_TOKEN_TRANSPORT_HEADER") ``` -{% /tab %} -{% tab label="Javascript" %} +{% /Tab %} + +{% Tab label="typescript" %} -```javascript +```typescript import { ChromaClient } from "chromadb"; const chromaClient = new ChromaClient({ @@ -273,8 +281,9 @@ const chromaClient = new ChromaClient({ chromaClient.heartbeat() ``` -{% /tab %} -{% /tabs %} +{% /Tab %} + +{% /Tabs %} ## Observability with AWS @@ -289,7 +298,7 @@ Tracing is configured with four environment variables: To enable tracing on your Chroma server, simply pass your desired values as parameters when creating your Cloudformation stack: -```shell +```terminal aws cloudformation create-stack --stack-name my-chroma-stack --template-url https://s3.amazonaws.com/public.trychroma.com/cloudformation/latest/chroma.cf.json \ --parameters ParameterKey=ChromaOtelCollectionEndpoint,ParameterValue="api.honeycomb.com" \ ParameterKey=ChromaOtelServiceName,ParameterValue="chromadb" \ @@ -301,4 +310,4 @@ aws cloudformation create-stack --stack-name my-chroma-stack --template-url http #### Error: No default VPC for this user -If you get an error saying `No default VPC for this user` when creating `ChromaInstanceSecurityGroup`, head to [AWS VPC section](https://us-east-1.console.aws.amazon.com/vpc/home?region=us-east-1#vpcs) and create a default VPC for your user. +If you get an error saying `No default VPC for this user` when creating `ChromaInstanceSecurityGroup`, head to [AWS VPC section](https://us-east-1.console.aws.amazon.com/vpc/home?region=us-east-1#vpcs) and create a default VPC for your user. \ No newline at end of file diff --git a/docs/docs.trychroma.com/pages/deployment/azure.md b/docs/docs.trychroma.com/markdoc/content/production/cloud-providers/azure.md similarity index 89% rename from docs/docs.trychroma.com/pages/deployment/azure.md rename to docs/docs.trychroma.com/markdoc/content/production/cloud-providers/azure.md index 948b18ecdcc..4d9bc766ffc 100644 --- a/docs/docs.trychroma.com/pages/deployment/azure.md +++ b/docs/docs.trychroma.com/markdoc/content/production/cloud-providers/azure.md @@ -1,25 +1,17 @@ ---- -title: "☁️ Azure Deployment" ---- +# Azure Deployment -{% tabs group="code-lang" hideContent=true %} +{% Banner type="tip" %} -{% tab label="Python" %} -{% /tab %} +**Hosted Chroma** -{% tab label="Javascript" %} -{% /tab %} - -{% /tabs %} - -{% note type="tip" title="Hosted Chroma" %} Chroma Cloud, our fully managed hosted service, is in early access. Fill out the survey to jump the waitlist and get the best retrieval experience. Full access coming Q1 2025. [📝 30 second survey](https://airtable.com/shrOAiDUtS2ILy5vZ) -{% /note %} +{% /Banner %} + +{% Banner type="tip" %} -{% note type="tip" title="" %} If you are using Chroma in production, please fill out [this form](https://airtable.com/appqd02UuQXCK5AuY/pagr1D0NFQoNpUpNZ/form), and we will add you to a dedicated Slack workspace for supporting production users. This is the best place to @@ -28,7 +20,8 @@ This is the best place to 3. Get swag! We would love to help you think through the design of your system, or if you would be a good fit for our upcoming distributed cloud service. -{% /note %} + +{% /Banner %} ## A Simple Azure Deployment @@ -39,26 +32,26 @@ For convenience, we have provided a very simple Terraform configuration to experiment with deploying Chroma to Azure. -{% note type="warning" title="" %} +{% Banner type="warn" %} Chroma and its underlying database [need at least 2GB of RAM](./performance#results-summary). When defining your VM size for the template in this example, make sure it meets this requirement. -{% /note %} +{% /Banner %} -{% note type="warning" title="" %} +{% Banner type="warn" %} In this guide we show you how to secure your endpoint using [Chroma's native authentication support](./azure#authentication-with-azure). Alternatively, you can put it behind an API Gateway or add your own authenticating proxy. This basic stack doesn't support any kind of authentication; anyone who knows your server IP will be able to add and query for embeddings. -{% /note %} +{% /Banner %} -{% note type="warning" title="" %} +{% Banner type="warn" %} By default, this template saves all data on a single volume. When you delete or replace it, the data will disappear. For serious production use (with high availability, backups, etc.) please read and understand the Terraform template and use it as a basis for what you need, or reach out to the Chroma team for assistance. -{% /note %} +{% /Banner %} ### Step 1: Install Terraform @@ -66,7 +59,7 @@ Download [Terraform](https://developer.hashicorp.com/terraform/install?product_i ### Step 2: Authenticate with Azure -```shell +```terminal az login ``` @@ -85,22 +78,22 @@ machine_type = "Standard_B1s" Download our [Azure Terraform configuration](https://github.com/chroma-core/chroma/blob/main/deployments/azure/main.tf) to the same directory as your `chroma.tfvars` file. Then run the following commands to deploy your Chroma stack. Initialize Terraform: -```shell +```terminal terraform init ``` Plan the deployment, and review it to ensure it matches your expectations: -```shell +```terminal terraform plan -var-file chroma.tfvars ``` Finally, apply the deployment: -```shell +```terminal terraform apply -var-file chroma.tfvars ``` After a few minutes, you can get the IP address of your instance with -```shell +```terminal terraform output -raw public_ip_address ``` @@ -108,10 +101,11 @@ terraform output -raw public_ip_address Once your Azure VM instance is up and running with Chroma, all you need to do is configure your `HttpClient` to use the server's IP address and port -`8000`. Since you are running a Chroma server on Azure, our [thin-client package](./thin-client.md) may be enough for your application. +`8000`. Since you are running a Chroma server on Azure, our [thin-client package](../chroma-server/python-thin-client) may be enough for your application. -{% tabs group="code-lang" hideTabs=true %} -{% tab label="Python" %} +{% TabbedCodeBlock %} + +{% Tab label="python" %} ```python import chromadb @@ -123,10 +117,11 @@ chroma_client = chromadb.HttpClient( chroma_client.heartbeat() ``` -{% /tab %} -{% tab label="Javascript" %} +{% /Tab %} + +{% Tab label="typescript" %} -```javascript +```typescript import { ChromaClient } from "chromadb"; const chromaClient = new ChromaClient({ @@ -136,35 +131,40 @@ const chromaClient = new ChromaClient({ chromaClient.heartbeat() ``` -{% /tab %} -{% /tabs %} +{% /Tab %} + +{% /TabbedCodeBlock %} ### Step 5: Clean Up (optional). To destroy the stack and remove all Azure resources, use the `terraform destroy` command. -{% note type="warning" title="Note" %} -This will destroy all the data in your Chroma database, -unless you've taken a snapshot or otherwise backed it up. -{% /note %} - ```shell terraform destroy -var-file chroma.tfvars ``` +{% Banner type="warn" %} +This will destroy all the data in your Chroma database, +unless you've taken a snapshot or otherwise backed it up. +{% /Banner %} + ## Authentication with Azure By default, the Azure VM instance created by our Terraform configuration will run with no authentication. There are many ways to secure your Chroma instance on Azure. In this guide we will use a simple set-up using Chroma's native authentication support. -You can learn more about authentication with Chroma in the [Auth Guide](/deployment/auth). +You can learn more about authentication with Chroma in the [Auth Guide](../administration/auth). ### Static API Token Authentication #### Customize Chroma's Terraform Configuration -{% note type="note" title="Security Note" %} +{% Banner type="note" %} + +**Security Note** + Current implementation of static API token auth supports only ENV based tokens. Tokens must be alphanumeric ASCII strings. Tokens are case-sensitive. -{% /note %} + +{% /Banner %} If, for example, you want the static API token to be "test-token", set the following variables in your `chroma.tfvars`. This will set `Authorization: Bearer test-token` as your authentication header. @@ -189,8 +189,9 @@ Add the `CHROMA_CLIENT_AUTH_CREDENTIALS` environment variable to your local envi export CHROMA_CLIENT_AUTH_CREDENTIALS="test-token" ``` -{% tabs group="code-lang" hideTabs=true %} -{% tab label="Python" %} +{% Tabs %} + +{% Tab label="python" %} We will use Chroma's `Settings` object to define the authentication method on the client. @@ -220,10 +221,11 @@ If you are using a custom `CHROMA_AUTH_TOKEN_TRANSPORT_HEADER` (like `X-Chroma-T chroma_auth_token_transport_header=os.getenv("CHROMA_AUTH_TOKEN_TRANSPORT_HEADER") ``` -{% /tab %} -{% tab label="Javascript" %} +{% /Tab %} + +{% Tab label="typescript" %} -```javascript +```typescript import { ChromaClient } from "chromadb"; const chromaClient = new ChromaClient({ @@ -238,8 +240,9 @@ const chromaClient = new ChromaClient({ chromaClient.heartbeat() ``` -{% /tab %} -{% /tabs %} +{% /Tab %} + +{% /Tabs %} ## Observability with Azure diff --git a/docs/docs.trychroma.com/pages/deployment/gcp.md b/docs/docs.trychroma.com/markdoc/content/production/cloud-providers/gcp.md similarity index 90% rename from docs/docs.trychroma.com/pages/deployment/gcp.md rename to docs/docs.trychroma.com/markdoc/content/production/cloud-providers/gcp.md index 9bee99952a9..92cbe226b0f 100644 --- a/docs/docs.trychroma.com/pages/deployment/gcp.md +++ b/docs/docs.trychroma.com/markdoc/content/production/cloud-providers/gcp.md @@ -1,26 +1,17 @@ ---- -title: "☁️ GCP Deployment" ---- +# GCP Deployment +{% Banner type="tip" %} -{% tabs group="code-lang" hideContent=true %} +**Hosted Chroma** -{% tab label="Python" %} -{% /tab %} - -{% tab label="Javascript" %} -{% /tab %} - -{% /tabs %} - -{% note type="tip" title="Hosted Chroma" %} Chroma Cloud, our fully managed hosted service, is in early access. Fill out the survey to jump the waitlist and get the best retrieval experience. Full access coming Q1 2025. [📝 30 second survey](https://airtable.com/shrOAiDUtS2ILy5vZ) -{% /note %} +{% /Banner %} + +{% Banner type="tip" %} -{% note type="tip" title="" %} If you are using Chroma in production, please fill out [this form](https://airtable.com/appqd02UuQXCK5AuY/pagr1D0NFQoNpUpNZ/form), and we will add you to a dedicated Slack workspace for supporting production users. This is the best place to @@ -29,7 +20,8 @@ This is the best place to 3. Get swag! We would love to help you think through the design of your system, or if you would be a good fit for our upcoming distributed cloud service. -{% /note %} + +{% /Banner %} ## A Simple GCP Deployment @@ -40,30 +32,36 @@ For convenience, we have provided a very simple Terraform configuration to experiment with deploying Chroma to Google Compute Engine. -{% note type="warning" title="" %} +{% Banner type="warn" %} + Chroma and its underlying database [need at least 2GB of RAM](./performance#results-summary), which means it won't fit on the instances provided as part of the GCP "always free" tier. This template uses an [`e2-small`](https://cloud.google.com/compute/docs/general-purpose-machines#e2_machine_types) instance, which costs about two cents an hour, or $15 for a full month, and gives you 2GiB of memory. If you follow these instructions, GCP will bill you accordingly. -{% /note %} -{% note type="warning" title="" %} +{% /Banner %} + +{% Banner type="warn" %} + In this guide we show you how to secure your endpoint using [Chroma's native authentication support](./gcp#authentication-with-gcp). Alternatively, you can put it behind [GCP API Gateway](https://cloud.google.com/api-gateway/docs) or add your own authenticating proxy. This basic stack doesn't support any kind of authentication; anyone who knows your server IP will be able to add and query for embeddings. -{% /note %} -{% note type="warning" title="" %} +{% /Banner %} + +{% Banner type="warn" %} + By default, this template saves all data on a single volume. When you delete or replace it, the data will disappear. For serious production use (with high availability, backups, etc.) please read and understand the Terraform template and use it as a basis for what you need, or reach out to the Chroma team for assistance. -{% /note %} + +{% /Banner %} ### Step 1: Set up your GCP credentials @@ -75,7 +73,7 @@ In your GCP project, create a service account for deploying Chroma. It will need Create a JSON key file for this service account, and download it. Set the `GOOGLE_APPLICATION_CREDENTIALS` environment variable to the path of your JSON key file: -```shell +```terminal export GOOGLE_APPLICATION_CREDENTIALS="/path/to/your/service-account-key.json" ``` @@ -98,18 +96,18 @@ zone="" Download our [GCP Terraform configuration](https://github.com/chroma-core/chroma/blob/main/deployments/gcp/main.tf) to the same directory as your `chroma.tfvars` file. Then run the following commands to deploy your Chroma stack. Initialize Terraform: -```shell +```terminal terraform init ``` Plan the deployment, and review it to ensure it matches your expectations: -```shell +```terminal terraform plan -var-file chroma.tfvars ``` If you did not customize our configuration, you should be deploying an `e2-small` instance. Finally, apply the deployment: -```shell +```terminal terraform apply -var-file chroma.tfvars ``` @@ -122,7 +120,7 @@ machine_type = "e2-medium" ``` After a few minutes, you can get the IP address of your instance with -```shell +```terminal terraform output -raw chroma_instance_ip ``` @@ -130,10 +128,11 @@ terraform output -raw chroma_instance_ip Once your Compute Engine instance is up and running with Chroma, all you need to do is configure your `HttpClient` to use the server's IP address and port -`8000`. Since you are running a Chroma server on GCP, our [thin-client package](./thin-client.md) may be enough for your application. +`8000`. Since you are running a Chroma server on GCP, our [thin-client package](../chroma-server/python-thin-client) may be enough for your application. + +{% TabbedCodeBlock %} -{% tabs group="code-lang" hideTabs=true %} -{% tab label="Python" %} +{% Tab label="python" %} ```python import chromadb @@ -145,10 +144,11 @@ chroma_client = chromadb.HttpClient( chroma_client.heartbeat() ``` -{% /tab %} -{% tab label="Javascript" %} +{% /Tab %} -```javascript +{% Tab label="typescript" %} + +```typescript import { ChromaClient } from "chromadb"; const chromaClient = new ChromaClient({ @@ -158,8 +158,9 @@ const chromaClient = new ChromaClient({ chromaClient.heartbeat() ``` -{% /tab %} -{% /tabs %} +{% /Tab %} + +{% /TabbedCodeBlock %} ### Step 5: Clean Up (optional). @@ -170,7 +171,7 @@ This will destroy all the data in your Chroma database, unless you've taken a snapshot or otherwise backed it up. {% /note %} -```shell +```terminal terraform destroy -var-file chroma.tfvars ``` @@ -178,15 +179,19 @@ terraform destroy -var-file chroma.tfvars By default, the Compute Engine instance created by our Terraform configuration will run with no authentication. There are many ways to secure your Chroma instance on GCP. In this guide we will use a simple set-up using Chroma's native authentication support. -You can learn more about authentication with Chroma in the [Auth Guide](/deployment/auth). +You can learn more about authentication with Chroma in the [Auth Guide](../administration/auth). ### Static API Token Authentication #### Customize Chroma's Terraform Configuration -{% note type="note" title="Security Note" %} +{% Banner type="note" %} + +**Security Note** + Current implementation of static API token auth supports only ENV based tokens. Tokens must be alphanumeric ASCII strings. Tokens are case-sensitive. -{% /note %} + +{% /Banner %} If, for example, you want the static API token to be "test-token", set the following variables in your `chroma.tfvars`. This will set `Authorization: Bearer test-token` as your authentication header. @@ -207,12 +212,13 @@ chroma_auth_token_transport_header = "X-Chroma-Token" Add the `CHROMA_CLIENT_AUTH_CREDENTIALS` environment variable to your local environment, and set it to the token you provided the server (`test-token` in this example): -```shell +```terminal export CHROMA_CLIENT_AUTH_CREDENTIALS="test-token" ``` -{% tabs group="code-lang" hideTabs=true %} -{% tab label="Python" %} +{% Tabs %} + +{% Tab label="python" %} We will use Chroma's `Settings` object to define the authentication method on the client. @@ -242,10 +248,11 @@ If you are using a custom `CHROMA_AUTH_TOKEN_TRANSPORT_HEADER` (like `X-Chroma-T chroma_auth_token_transport_header=os.getenv("CHROMA_AUTH_TOKEN_TRANSPORT_HEADER") ``` -{% /tab %} -{% tab label="Javascript" %} +{% /Tab %} + +{% Tab label="typescript" %} -```javascript +```typescript import { ChromaClient } from "chromadb"; const chromaClient = new ChromaClient({ @@ -260,8 +267,9 @@ const chromaClient = new ChromaClient({ chromaClient.heartbeat() ``` -{% /tab %} -{% /tabs %} +{% /Tab %} + +{% /Tabs %} ## Observability with GCP diff --git a/docs/docs.trychroma.com/pages/deployment/docker.md b/docs/docs.trychroma.com/markdoc/content/production/containers/docker.md similarity index 90% rename from docs/docs.trychroma.com/pages/deployment/docker.md rename to docs/docs.trychroma.com/markdoc/content/production/containers/docker.md index a410d7338ed..632f7c614fd 100644 --- a/docs/docs.trychroma.com/pages/deployment/docker.md +++ b/docs/docs.trychroma.com/markdoc/content/production/containers/docker.md @@ -1,23 +1,27 @@ ---- -title: Docker ---- +# Docker -{% tabs group="code-lang" hideContent=true %} +{% Banner type="tip" %} -{% tab label="Python" %} -{% /tab %} +**Hosted Chroma** -{% tab label="Javascript" %} -{% /tab %} - -{% /tabs %} - -{% note type="tip" title="Hosted Chroma" %} Chroma Cloud, our fully managed hosted service, is in early access. Fill out the survey to jump the waitlist and get the best retrieval experience. Full access coming Q1 2025. [📝 30 second survey](https://airtable.com/shrOAiDUtS2ILy5vZ) -{% /note %} +{% /Banner %} + +{% Banner type="tip" %} + +If you are using Chroma in production, please fill out [this form](https://airtable.com/appqd02UuQXCK5AuY/pagr1D0NFQoNpUpNZ/form), and we will add you to a dedicated Slack workspace for supporting production users. +This is the best place to + +1. Get support with building with Chroma in prod. +2. Stay up-to-date with exciting new features. +3. Get swag! + +We would love to help you think through the design of your system, or if you would be a good fit for our upcoming distributed cloud service. + +{% /Banner %} ## Run Chroma in a Docker Container @@ -25,18 +29,18 @@ You can run a Chroma server in a Docker container, and access it using the `Http If you are using Chroma in production, please fill out [this form](https://airtable.com/appqd02UuQXCK5AuY/pagr1D0NFQoNpUpNZ/form), and we will add you to a dedicated Slack workspace for supporting production users. We would love to help you think through the design of your system, or if you would be a good fit for our upcoming distributed cloud service. -If you are using a client in a separate container from the one running your Chroma server, you may only need the [thin-client package](./thin-client) +If you are using a client in a separate container from the one running your Chroma server, you may only need the [thin-client package](../chroma-server/python-thin-client) You can get the Chroma Docker image from [Docker Hub](https://hub.docker.com/r/chromadb/chroma), or from the [Chroma GitHub Container Registry](https://github.com/chroma-core/chroma/pkgs/container/chroma) -```sh +```terminal docker pull chromadb/chroma docker run -p 8000:8000 chromadb/chroma ``` You can also build the Docker image yourself from the Dockerfile in the [Chroma GitHub repository](https://github.com/chroma-core/chroma) -```sh +```terminal git clone git@github.com:chroma-core/chroma.git cd chroma docker-compose up -d --build @@ -44,27 +48,26 @@ docker-compose up -d --build The Chroma client can then be configured to connect to the server running in the Docker container. -{% tabs group="code-lang" hideTabs=true %} -{% tab label="Python" %} +{% TabbedCodeBlock %} +{% Tab label="python" %} ```python import chromadb chroma_client = chromadb.HttpClient(host='localhost', port=8000) chroma_client.heartbeat() ``` +{% /Tab %} -{% /tab %} -{% tab label="Javascript" %} - -```javascript +{% Tab label="typescript" %} +```typescript import { ChromaClient } from "chromadb"; const chromaClient = new ChromaClient({ path: "http://localhost:8000" }) chromaClient.heartbeat() ``` +{% /Tab %} -{% /tab %} -{% /tabs %} +{% /TabbedCodeBlock %} ## Authentication with Docker @@ -72,7 +75,7 @@ By default, the Docker image will run with no authentication. In client/server m * [RFC 7617](https://www.rfc-editor.org/rfc/rfc7617) Basic Auth with `user:password` base64-encoded `Authorization` header. * Static auth token in `Authorization: Bearer ` or in `X-Chroma-Token: ` headers. -You can learn more about authentication with Chroma in the [Auth Guide](/deployment/auth). +You can learn more about authentication with Chroma in the [Auth Guide](../administration/auth). ### Encrypted User:Password Authentication @@ -81,12 +84,12 @@ You can learn more about authentication with Chroma in the [Auth Guide](/deploym ##### Generate Server-Side Credentials {% note type="note" title="Security Practices" %} -A good security practice is to store the password securely. In the example below we use [bcrypt](https://en.wikipedia.org/wiki/Bcrypt) (currently the only supported hash in Chroma server side auth) to hash the plaintext password. If you'd like to see support for additional hash functions, feel free to [contribute](../contributing) new ones! +A good security practice is to store the password securely. In the example below we use [bcrypt](https://en.wikipedia.org/wiki/Bcrypt) (currently the only supported hash in Chroma server side auth) to hash the plaintext password. If you'd like to see support for additional hash functions, feel free to [contribute](../../docs/overview/contributing) new ones! {% /note %} To generate the password hash, run the following command: -```bash +```terminal docker run --rm --entrypoint htpasswd httpd:2 -Bbn admin admin > server.htpasswd ``` @@ -103,7 +106,7 @@ CHROMA_SERVER_AUTHN_PROVIDER=chromadb.auth.basic_authn.BasicAuthenticationServer Then, run the Chroma container, and pass it your `.chroma_env` using the `--env-file` flag: -```bash +```terminal docker run --env-file ./.chroma_env -p 8000:8000 chromadb/chroma ``` @@ -111,12 +114,13 @@ docker run --env-file ./.chroma_env -p 8000:8000 chromadb/chroma In your client environment, set the `CHROMA_CLIENT_AUTH_CREDENTIALS` variable to the user:password combination (`admin:admin` in this example): -```shell +```terminal export CHROMA_CLIENT_AUTH_CREDENTIALS="admin:admin" ``` -{% tabs group="code-lang" hideTabs=true %} -{% tab label="Python" %} +{% Tabs %} + +{% Tab label="python" %} Install `python-dotenv`. This will allow us to read the environment variables from `.chroma_env` easily: @@ -146,10 +150,11 @@ client = chromadb.HttpClient( chroma_client.heartbeat() ``` -{% /tab %} -{% tab label="Javascript" %} +{% /Tab %} + +{% Tab label="typescript" %} -```javascript +```typescript import { ChromaClient } from "chromadb"; const chromaClient = new ChromaClient({ @@ -163,16 +168,21 @@ const chromaClient = new ChromaClient({ chromaClient.heartbeat() ``` -{% /tab %} -{% /tabs %} +{% /Tab %} + +{% /Tabs %} ### Static API Token Authentication #### Server Set-Up -{% note type="note" title="Security Note" %} +{% Banner type="note" %} + +**Security Note** + Current implementation of static API token auth supports only ENV based tokens. Tokens must be alphanumeric ASCII strings. Tokens are case-sensitive. -{% /note %} + +{% /Banner %} If, for example, you want the static API token to be "test-token", add the following environment variables to your `.chroma_env`. This will set `Authorization: Bearer test-token` as your authentication header. @@ -191,7 +201,7 @@ CHROMA_AUTH_TOKEN_TRANSPORT_HEADER=X-Chroma-Token Then, run the Chroma server: -```bash +```terminal docker run --env-file ./.chroma_env -p 8000:8000 chromadb/chroma ``` @@ -206,14 +216,15 @@ CHROMA_SERVER_AUTHZ_PROVIDER=chromadb.auth.simple_rbac_authz.SimpleRBACAuthoriza In this case, you will have to set up a volume to allow the Chroma Docker container to use your `authz.yaml` file: -```bash +```terminal docker run --env-file ./.chroma_env -v :/chroma/ -p 8000:8000 chromadb/chroma ``` #### Client Set-Up -{% tabs group="code-lang" hideTabs=true %} -{% tab label="Python" %} +{% Tabs %} + +{% Tab label="python" %} Install `python-dotenv`. This will allow us to read the environment variables from `.chroma_env` easily: @@ -249,10 +260,11 @@ If you are using a custom `CHROMA_AUTH_TOKEN_TRANSPORT_HEADER` (like `X-Chroma-T chroma_auth_token_transport_header=os.getenv("CHROMA_AUTH_TOKEN_TRANSPORT_HEADER") ``` -{% /tab %} -{% tab label="Javascript" %} +{% /Tab %} -```javascript +{% Tab label="typescript" %} + +```typescript import { ChromaClient } from "chromadb"; const chromaClient = new ChromaClient({ @@ -267,8 +279,9 @@ const chromaClient = new ChromaClient({ chromaClient.heartbeat() ``` -{% /tab %} -{% /tabs %} +{% /Tab %} + +{% /Tabs %} ## Observability with Docker @@ -369,12 +382,16 @@ volumes: To start the stack, run from the root of the repo: -```bash +```terminal docker compose up --build -d ``` Once the stack is running, you can access Zipkin at http://localhost:9411 when running locally to see your traces. -{% note type="tip" title="Traces" %} +{% Banner type="tip" %} + +**Traces** + Traces in Zipkin will start appearing after you make a request to Chroma. -{% /note %} \ No newline at end of file + +{% /Banner %} \ No newline at end of file diff --git a/docs/docs.trychroma.com/pages/deployment/index.md b/docs/docs.trychroma.com/markdoc/content/production/deployment.md similarity index 58% rename from docs/docs.trychroma.com/pages/deployment/index.md rename to docs/docs.trychroma.com/markdoc/content/production/deployment.md index cdf93628de8..4f89a4dba21 100644 --- a/docs/docs.trychroma.com/pages/deployment/index.md +++ b/docs/docs.trychroma.com/markdoc/content/production/deployment.md @@ -1,17 +1,17 @@ ---- -title: ☁️ Deployment ---- +# Deployment -*** +{% Banner type="tip" %} + +**Hosted Chroma** -{% note type="tip" title="Hosted Chroma" %} Chroma Cloud, our fully managed hosted service, is in early access. Fill out the survey to jump the waitlist and get the best retrieval experience. Full access coming Q1 2025. [📝 30 second survey](https://airtable.com/shrOAiDUtS2ILy5vZ) -{% /note %} +{% /Banner %} + +{% Banner type="tip" %} -{% note type="tip" title="" %} If you are using Chroma in production, please fill out [this form](https://airtable.com/appqd02UuQXCK5AuY/pagr1D0NFQoNpUpNZ/form), and we will add you to a dedicated Slack workspace for supporting production users. This is the best place to @@ -20,20 +20,21 @@ This is the best place to 3. Get swag! We would love to help you think through the design of your system, or if you would be a good fit for our upcoming distributed cloud service. -{% /note %} -You can run Chroma single-node in [client/server mode](/deployment/client-server-mode), and easily deploy it. In this section, we also show you how to make sure your Chroma server is secure and reliable, and how to understand its performance at scale. +{% /Banner %} + +You can run Chroma single-node in [client/server mode](./chroma-server/client-server-mode), and easily deploy it. In this section, we also show you how to make sure your Chroma server is secure and reliable, and how to understand its performance at scale. ### Containers -* 🐳 [Docker](/deployment/docker) +* [Docker](./containers/docker) * Kubernetes - Coming Soon! ### Cloud Providers -* [AWS](/deployment/aws) -* [GCP](/deployment/gcp) -* [Azure](/deployment/azure) +* [AWS](./cloud-providers/aws) +* [GCP](./cloud-providers/gcp) +* [Azure](./cloud-providers/azure) *** @@ -41,7 +42,8 @@ You can run Chroma single-node in [client/server mode](/deployment/client-server Running a server in production requires a few additional steps to ensure the server is secure and reliable. -* [🚀 Performance](/deployment/performance) -* [👀 Observability](/deployment/observability) -* [✈️ Migration](/deployment/migration) -* [🔒 Auth](/deployment/auth) +* [Performance](./administration/performance) +* [Observability](./administration/observability) +* [Auth](./administration/auth) +* [Migration](./administration/migration) + diff --git a/docs/docs.trychroma.com/pages/reference/index.md b/docs/docs.trychroma.com/markdoc/content/reference/chroma-reference.md similarity index 63% rename from docs/docs.trychroma.com/pages/reference/index.md rename to docs/docs.trychroma.com/markdoc/content/reference/chroma-reference.md index 309cefbb885..1ba8c54f81f 100644 --- a/docs/docs.trychroma.com/pages/reference/index.md +++ b/docs/docs.trychroma.com/markdoc/content/reference/chroma-reference.md @@ -1,6 +1,4 @@ ---- -title: 🔧 Reference ---- +# Chroma Reference ## Client APIs @@ -14,10 +12,10 @@ Chroma currently maintains 1st party clients for Python and Javascript. For othe {% special_table %} {% /special_table %} -| | Client | Collection | -|--------------|-----------|---------------| -| Python | [Client](/reference/py-client) | [Collection](/reference/py-collection) | -| Javascript | [Client](/reference/js-client) | [Collection](/reference/js-collection) | +| | Client | Collection | +|--------------|-----------------------|-----------------------------------| +| Python | [Client](./python/client) | [Collection](./python/collection) | +| Javascript | [Client](./js/client) | [Collection](./js/collection) | *** diff --git a/docs/docs.trychroma.com/pages/reference/js-client.md b/docs/docs.trychroma.com/markdoc/content/reference/js/client.md similarity index 67% rename from docs/docs.trychroma.com/pages/reference/js-client.md rename to docs/docs.trychroma.com/markdoc/content/reference/js/client.md index 755d6d65f64..ec815ddbc10 100644 --- a/docs/docs.trychroma.com/pages/reference/js-client.md +++ b/docs/docs.trychroma.com/markdoc/content/reference/js/client.md @@ -1,16 +1,10 @@ ---- -title: JS Client ---- +# JS Client -# Class: ChromaClient - -[ChromaClient](../modules/ChromaClient.md).ChromaClient - -## Constructors +## Class: ChromaClient ### constructor -• **new ChromaClient**(`params?`) +* `new ChromaClient(params?)` Creates a new ChromaClient instance. @@ -20,7 +14,7 @@ Creates a new ChromaClient instance. | :------ | :------ | :------ | | `params` | `ChromaClientParams` | The parameters for creating a new client | -**`Example`** +**Example** ```typescript const client = new ChromaClient({ @@ -32,31 +26,29 @@ const client = new ChromaClient({ ### countCollections -▸ **countCollections**(): `Promise`\<`number`\> +* `countCollections(): Promise` Counts all collections. #### Returns -`Promise`\<`number`\> +`Promise` A promise that resolves to the number of collections. -**`Throws`** +**Throws** If there is an issue counting the collections. -**`Example`** +**Example** ```typescript const collections = await client.countCollections(); ``` -___ - ### createCollection -▸ **createCollection**(`params`): `Promise`\<[`Collection`](Collection.Collection.md)\> +* `createCollection(params): Promise` Creates a new collection with the specified properties. @@ -68,19 +60,16 @@ Creates a new collection with the specified properties. #### Returns -`Promise`\<[`Collection`](Collection.Collection.md)\> +`Promise` A promise that resolves to the created collection. -**`Throws`** - -If the client is unable to connect to the server. - -**`Throws`** +**Throws** -If there is an issue creating the collection. +* If the client is unable to connect to the server. +* If there is an issue creating the collection. -**`Example`** +**Example** ```typescript const collection = await client.createCollection({ @@ -91,11 +80,9 @@ const collection = await client.createCollection({ }); ``` -___ - ### deleteCollection -▸ **deleteCollection**(`params`): `Promise`\<`void`\> +* `deleteCollection(params): Promise` Deletes a collection with the specified name. @@ -107,15 +94,15 @@ Deletes a collection with the specified name. #### Returns -`Promise`\<`void`\> +`Promise` A promise that resolves when the collection is deleted. -**`Throws`** +**Throws** If there is an issue deleting the collection. -**`Example`** +**Example** ```typescript await client.deleteCollection({ @@ -123,11 +110,9 @@ await client.deleteCollection({ }); ``` -___ - ### getCollection -▸ **getCollection**(`params`): `Promise`\<[`Collection`](Collection.Collection.md)\> +`getCollection(params): Promise` Gets a collection with the specified name. @@ -139,15 +124,15 @@ Gets a collection with the specified name. #### Returns -`Promise`\<[`Collection`](Collection.Collection.md)\> +`Promise` A promise that resolves to the collection. -**`Throws`** +**Throws** If there is an issue getting the collection. -**`Example`** +**Example** ```typescript const collection = await client.getCollection({ @@ -155,11 +140,9 @@ const collection = await client.getCollection({ }); ``` -___ - ### getOrCreateCollection -▸ **getOrCreateCollection**(`params`): `Promise`\<[`Collection`](Collection.Collection.md)\> +* `getOrCreateCollection(params): Promise` Gets or creates a collection with the specified properties. @@ -171,15 +154,15 @@ Gets or creates a collection with the specified properties. #### Returns -`Promise`\<[`Collection`](Collection.Collection.md)\> +`Promise` A promise that resolves to the got or created collection. -**`Throws`** +**Throws** If there is an issue getting or creating the collection. -**`Example`** +**Example** ```typescript const collection = await client.getOrCreateCollection({ @@ -190,55 +173,51 @@ const collection = await client.getOrCreateCollection({ }); ``` -___ - ### heartbeat -▸ **heartbeat**(): `Promise`\<`number`\> +* `heartbeat(): Promise` Returns a heartbeat from the Chroma API. #### Returns -`Promise`\<`number`\> +`Promise` A promise that resolves to the heartbeat from the Chroma API. -**`Throws`** +**Throws** If the client is unable to connect to the server. -**`Example`** +**Example** ```typescript const heartbeat = await client.heartbeat(); ``` -___ - ### listCollections -▸ **listCollections**(`«destructured»?`): `Promise`\<`CollectionParams`[]\> +* `listCollections(params?): Promise` Lists all collections. #### Parameters -| Name | Type | -| :------ | :------ | -| `«destructured»` | `ListCollectionsParams` | +| Name | Type | +|:---------| :------ | +| `params` | `ListCollectionsParams` | #### Returns -`Promise`\<`CollectionParams`[]\> +`Promise` A promise that resolves to a list of collection names. -**`Throws`** +**Throws** If there is an issue listing the collections. -**`Example`** +**Example** ```typescript const collections = await client.listCollections({ @@ -247,53 +226,46 @@ const collections = await client.listCollections({ }); ``` -___ - ### reset -▸ **reset**(): `Promise`\<`boolean`\> +* `reset(): Promise` Resets the state of the object by making an API call to the reset endpoint. #### Returns -`Promise`\<`boolean`\> +`Promise` A promise that resolves when the reset operation is complete. -**`Throws`** +**Throws** -If the client is unable to connect to the server. - -**`Throws`** +* If the client is unable to connect to the server. +* If the server experienced an error while the state. -If the server experienced an error while the state. - -**`Example`** +**Example** ```typescript await client.reset(); ``` -___ - ### version -▸ **version**(): `Promise`\<`string`\> +* `version(): Promise` Returns the version of the Chroma API. #### Returns -`Promise`\<`string`\> +`Promise` A promise that resolves to the version of the Chroma API. -**`Throws`** +**Throws** If the client is unable to connect to the server. -**`Example`** +**Example** ```typescript const version = await client.version(); diff --git a/docs/docs.trychroma.com/pages/reference/js-collection.md b/docs/docs.trychroma.com/markdoc/content/reference/js/collection.md similarity index 73% rename from docs/docs.trychroma.com/pages/reference/js-collection.md rename to docs/docs.trychroma.com/markdoc/content/reference/js/collection.md index 6533c04490f..0b693b393ee 100644 --- a/docs/docs.trychroma.com/pages/reference/js-collection.md +++ b/docs/docs.trychroma.com/markdoc/content/reference/js/collection.md @@ -1,34 +1,16 @@ ---- -title: JS Collection ---- - # Class: Collection -[Collection](../modules/Collection.md).Collection - ## Properties -### id - -• **id**: `string` - -___ - -### metadata - -• **metadata**: `CollectionMetadata` - -___ - -### name - -• **name**: `string` +* `id: string` +* `metadata: CollectionMetadata` +* `name: string` ## Methods ### add -▸ **add**(`params`): `Promise`\<`void`\> +* `add(params): Promise` Add items to the collection @@ -40,11 +22,11 @@ Add items to the collection #### Returns -`Promise`\<`void`\> +`Promise` -- The response from the API. True if successful. +- The response from the API. -**`Example`** +**Example** ```typescript const response = await collection.add({ @@ -55,31 +37,27 @@ const response = await collection.add({ }); ``` -___ - ### count -▸ **count**(): `Promise`\<`number`\> +* `count(): Promise` Count the number of items in the collection #### Returns -`Promise`\<`number`\> +`Promise` - The number of items in the collection. -**`Example`** +**Example** ```typescript const count = await collection.count(); ``` -___ - ### delete -▸ **delete**(`params?`): `Promise`\<`string`[]\> +* `delete(params?): Promise` Deletes items from the collection. @@ -91,15 +69,15 @@ Deletes items from the collection. #### Returns -`Promise`\<`string`[]\> +`Promise` A promise that resolves to the IDs of the deleted items. -**`Throws`** +**Throws** If there is an issue deleting items from the collection. -**`Example`** +**Example** ```typescript const results = await collection.delete({ @@ -109,11 +87,9 @@ const results = await collection.delete({ }); ``` -___ - ### get -▸ **get**(`params?`): `Promise`\<`MultiGetResponse`\> +* `get(params?): Promise` Get items from the collection @@ -125,11 +101,11 @@ Get items from the collection #### Returns -`Promise`\<`MultiGetResponse`\> +`Promise` -- The response from the server. +The response from the server. -**`Example`** +**Example** ```typescript const response = await collection.get({ @@ -142,11 +118,9 @@ const response = await collection.get({ }); ``` -___ - ### modify -▸ **modify**(`params`): `Promise`\<`CollectionParams`\> +* `modify(params): Promise` Modify the collection name or metadata @@ -160,11 +134,11 @@ Modify the collection name or metadata #### Returns -`Promise`\<`CollectionParams`\> +`Promise` -- The response from the API. +The response from the API. -**`Example`** +**Example** ```typescript const response = await client.updateCollection({ @@ -173,11 +147,9 @@ const response = await client.updateCollection({ }); ``` -___ - ### peek -▸ **peek**(`params?`): `Promise`\<`MultiGetResponse`\> +* `peek(params?): Promise` Peek inside the collection @@ -189,15 +161,15 @@ Peek inside the collection #### Returns -`Promise`\<`MultiGetResponse`\> +`Promise` A promise that resolves to the query results. -**`Throws`** +**Throws** If there is an issue executing the query. -**`Example`** +**Example** ```typescript const results = await collection.peek({ @@ -205,11 +177,9 @@ const results = await collection.peek({ }); ``` -___ - ### query -▸ **query**(`params`): `Promise`\<`MultiQueryResponse`\> +* `query(params): Promise` Performs a query on the collection using the specified parameters. @@ -221,43 +191,37 @@ Performs a query on the collection using the specified parameters. #### Returns -`Promise`\<`MultiQueryResponse`\> +`Promise` A promise that resolves to the query results. -**`Throws`** +**Throws** If there is an issue executing the query. -**`Example`** +**Example** -```ts +```typescript // Query the collection using embeddings -const results = await collection.query({ +const embeddingsResults = await collection.query({ queryEmbeddings: [[0.1, 0.2, ...], ...], nResults: 10, where: {"name": {"$eq": "John Doe"}}, include: ["metadata", "document"] }); -``` -**`Example`** - -```js // Query the collection using query text -const results = await collection.query({ - queryTexts: "some text", - nResults: 10, - where: {"name": {"$eq": "John Doe"}}, - include: ["metadata", "document"] +const textResults = await collection.query({ + queryTexts: "some text", + nResults: 10, + where: {"name": {"$eq": "John Doe"}}, + include: ["metadata", "document"] }); ``` -___ - ### update -▸ **update**(`params`): `Promise`\<`void`\> +* `update(params): Promise` Update items in the collection @@ -269,9 +233,9 @@ Update items in the collection #### Returns -`Promise`\<`void`\> +`Promise` -**`Example`** +**Example** ```typescript const response = await collection.update({ @@ -282,11 +246,9 @@ const response = await collection.update({ }); ``` -___ - ### upsert -▸ **upsert**(`params`): `Promise`\<`void`\> +* `upsert(params): Promise` Upsert items to the collection @@ -298,9 +260,9 @@ Upsert items to the collection #### Returns -`Promise`\<`void`\> +`Promise` -**`Example`** +**Example** ```typescript const response = await collection.upsert({ diff --git a/docs/docs.trychroma.com/pages/reference/py-client.md b/docs/docs.trychroma.com/markdoc/content/reference/python/client.md similarity index 90% rename from docs/docs.trychroma.com/pages/reference/py-client.md rename to docs/docs.trychroma.com/markdoc/content/reference/python/client.md index e9be33571f6..1584a28d6df 100644 --- a/docs/docs.trychroma.com/pages/reference/py-client.md +++ b/docs/docs.trychroma.com/markdoc/content/reference/python/client.md @@ -1,7 +1,4 @@ ---- -title: Client ---- - +# Python Client ## configure @@ -110,7 +107,7 @@ def CloudClient(tenant: str, enable_ssl: bool = True) -> ClientAPI ``` -Creates a client to connect to a tennant and database on the Chroma cloud. +Creates a client to connect to a tenant and database on the Chroma cloud. **Arguments**: @@ -126,10 +123,12 @@ def Client(settings: Settings = __settings, database: str = DEFAULT_DATABASE) -> ClientAPI ``` -Return a running chroma.API instance +Return a running `chroma.API` instance + +**Arguments**: -tenant: The tenant to use for this client. Defaults to the default tenant. -database: The database to use for this client. Defaults to the default database. +* `tenant`: The tenant to use for this client. Defaults to the `default` tenant. +* `database`: The database to use for this client. Defaults to the `default` database. ## AdminClient @@ -139,6 +138,7 @@ def AdminClient(settings: Settings = Settings()) -> AdminAPI Creates an admin client that can be used to create tenants and databases. +*** # BaseClient Methods @@ -174,10 +174,10 @@ Count the number of collections. **Examples**: - ```python - client.count_collections() - # 1 - ``` +```python +client.count_collections() +# 1 +``` ## delete\_collection @@ -247,6 +247,8 @@ def get_max_batch_size() -> int Return the maximum number of records that can be created or mutated in a single call. +*** + # ClientClient Methods ```python @@ -257,10 +259,10 @@ class ClientAPI(BaseAPI, ABC) ```python def list_collections(limit: Optional[int] = None, - offset: Optional[int] = None) -> List[str] + offset: Optional[int] = None) -> Sequence[Collection] ``` -List all collection names. +List all collections. **Arguments**: @@ -280,7 +282,7 @@ client.list_collections() # [collection(name="my_collection", metadata={})] ``` -## create\_collection +## create_collection ```python def create_collection(name: str, @@ -317,19 +319,20 @@ Create a new collection with the given name and metadata. **Examples**: - ```python - client.create_collection("my_collection") - # collection(name="my_collection", metadata={}) +```python +client.create_collection("my_collection") +# collection(name="my_collection", metadata={}) - client.create_collection("my_collection", metadata={"foo": "bar"}) - # collection(name="my_collection", metadata={"foo": "bar"}) - ``` +client.create_collection("my_collection", metadata={"foo": "bar"}) +# collection(name="my_collection", metadata={"foo": "bar"}) +``` -## get\_collection +## get_collection ```python def get_collection( name: str, + id: Optional[UUID] = None, embedding_function: Optional[ EmbeddingFunction[Embeddable]] = ef.DefaultEmbeddingFunction(), data_loader: Optional[DataLoader[Loadable]] = None) -> Collection @@ -358,10 +361,10 @@ Get a collection with the given name. **Examples**: - ```python - client.get_collection("my_collection") - # collection(name="my_collection", metadata={}) - ``` + ```python + client.get_collection("my_collection") + # collection(name="my_collection", metadata={}) + ``` ## get\_or\_create\_collection @@ -394,12 +397,12 @@ Get or create a collection with the given name and metadata. **Examples**: - ```python - client.get_or_create_collection("my_collection") - # collection(name="my_collection", metadata={}) - ``` + ```python + client.get_or_create_collection("my_collection") + # collection(name="my_collection", metadata={}) + ``` -## set\_tenant +## set_tenant ```python def set_tenant(tenant: str, database: str = DEFAULT_DATABASE) -> None @@ -413,7 +416,7 @@ database does not exist. - `tenant` - The tenant to set. - `database` - The database to set. -## set\_database +## set_database ```python def set_database(database: str) -> None @@ -425,7 +428,7 @@ Set the database for the client. Raises an error if the database does not exist. - `database` - The database to set. -## clear\_system\_cache +## clear_system_cache ```python @staticmethod @@ -435,13 +438,15 @@ def clear_system_cache() -> None Clear the system cache so that new systems can be created for an existing path. This should only be used for testing purposes. +*** + # AdminClient Methods ```python class AdminAPI(ABC) ``` -## create\_database +## create_database ```python def create_database(name: str, tenant: str = DEFAULT_TENANT) -> None @@ -453,7 +458,7 @@ Create a new database. Raises an error if the database already exists. - `database` - The name of the database to create. -## get\_database +## get_database ```python def get_database(name: str, tenant: str = DEFAULT_TENANT) -> Database @@ -466,7 +471,7 @@ Get a database. Raises an error if the database does not exist. - `database` - The name of the database to get. - `tenant` - The tenant of the database to get. -## create\_tenant +## create_tenant ```python def create_tenant(name: str) -> None @@ -478,7 +483,7 @@ Create a new tenant. Raises an error if the tenant already exists. - `tenant` - The name of the tenant to create. -## get\_tenant +## get_tenant ```python def get_tenant(name: str) -> Tenant @@ -490,6 +495,8 @@ Get a tenant. Raises an error if the tenant does not exist. - `tenant` - The name of the tenant to get. +*** + # ServerClient Methods ```python diff --git a/docs/docs.trychroma.com/pages/reference/py-collection.md b/docs/docs.trychroma.com/markdoc/content/reference/python/collection.md similarity index 98% rename from docs/docs.trychroma.com/pages/reference/py-collection.md rename to docs/docs.trychroma.com/markdoc/content/reference/python/collection.md index 3202689e504..208122e6d8f 100644 --- a/docs/docs.trychroma.com/pages/reference/py-collection.md +++ b/docs/docs.trychroma.com/markdoc/content/reference/python/collection.md @@ -2,13 +2,13 @@ title: Collection --- -# Collection Objects +# Python Collection ```python class Collection(BaseModel) ``` -# count +## count ```python def count() -> int @@ -20,7 +20,7 @@ The total number of embeddings added to the database - `int` - The total number of embeddings added to the database -# add +## add ```python def add(ids: OneOrMany[ID], @@ -51,7 +51,7 @@ Add embeddings to the data store. - `ValueError` - If you don't provide an embedding function and don't provide embeddings - `DuplicateIDError` - If you provide an id that already exists -# get +## get ```python def get(ids: Optional[OneOrMany[ID]] = None, @@ -79,7 +79,7 @@ all embeddings up to limit starting at offset. - `GetResult` - A GetResult object containing the results. -# peek +## peek ```python def peek(limit: int = 10) -> GetResult @@ -96,7 +96,7 @@ Get the first few results in the database up to limit - `GetResult` - A GetResult object containing the results. -# query +## query ```python def query( @@ -131,7 +131,7 @@ Get the n_results nearest neighbor embeddings for provided query_embeddings or q - `ValueError` - If you don't provide either query_embeddings or query_texts - `ValueError` - If you provide both query_embeddings and query_texts -# modify +## modify ```python def modify(name: Optional[str] = None, @@ -150,7 +150,7 @@ Modify the collection name or metadata None -# update +## update ```python def update(ids: OneOrMany[ID], @@ -173,7 +173,7 @@ Update the embeddings, metadatas or documents for provided ids. None -# upsert +## upsert ```python def upsert(ids: OneOrMany[ID], @@ -196,7 +196,7 @@ Update the embeddings, metadatas or documents for provided ids, or create them i None -# delete +## delete ```python def delete(ids: Optional[IDs] = None, diff --git a/docs/docs.trychroma.com/markdoc/content/sidebar-config.ts b/docs/docs.trychroma.com/markdoc/content/sidebar-config.ts new file mode 100644 index 00000000000..498cc1795b2 --- /dev/null +++ b/docs/docs.trychroma.com/markdoc/content/sidebar-config.ts @@ -0,0 +1,198 @@ +import { + BlocksIcon, + BookText, + GraduationCap, + RocketIcon, + SquareTerminalIcon, + WrenchIcon, +} from "lucide-react"; +import { AppSection } from "@/lib/content"; +import CloudIcon from "@/components/sidebar/cloud-icon"; + +const sidebarConfig: AppSection[] = [ + { + id: "docs", + name: "Docs", + default: "/overview/introduction", + icon: BookText, + subsections: [ + { + id: "overview", + name: "Overview", + pages: [ + { + id: "introduction", + name: "Introduction", + }, + { + id: "getting-started", + name: "Getting Started", + }, + { + id: "roadmap", + name: "Roadmap", + }, + { + id: "contributing", + name: "Contributing", + }, + { + id: "telemetry", + name: "Telemetry", + }, + { + id: "about", + name: "About", + }, + ], + }, + { + id: "run-chroma", + name: "Run Chroma", + pages: [ + { id: "ephemeral-client", name: "Ephemeral Client" }, + { id: "persistent-client", name: "Persistent Client" }, + { id: "client-server", name: "Client-Server Mode" }, + { id: "python-http-client", name: "Python HTTP-Only Client" }, + ], + }, + { + id: "collections", + name: "Collections", + pages: [ + { id: "create-get-delete", name: "Create, Get, Delete" }, + { id: "configure", name: "Configure" }, + { id: "add-data", name: "Add Data" }, + { id: "update-data", name: "Update Data" }, + { id: "delete-data", name: "Delete Data" }, + ], + }, + { + id: "querying-collections", + name: "Querying Collections", + pages: [ + { id: "query-and-get", name: "Query And Get" }, + { id: "metadata-filtering", name: "Metadata Filtering" }, + { id: "full-text-search", name: "Full Text Search" }, + ], + }, + { + id: "embeddings", + name: "Embeddings", + pages: [ + { id: "embedding-functions", name: "Embedding Functions" }, + { id: "multimodal", name: "Multimodal" }, + ], + }, + ], + }, + { + id: "cloud", + name: "Chroma Cloud", + icon: CloudIcon, + override: "https://airtable.com/appG6DhLoDUnTawwh/shrOAiDUtS2ILy5vZ", + }, + { + id: "production", + name: "Production", + default: "deployment", + icon: RocketIcon, + pages: [{ id: "deployment", name: "Deployment" }], + subsections: [ + { + id: "chroma-server", + name: "Chroma Server", + pages: [ + { id: "client-server-mode", name: "Client Server Mode" }, + { id: "python-thin-client", name: "Python Thin Client" }, + ], + }, + { + id: "containers", + name: "Containers", + pages: [{ id: "docker", name: "Docker" }], + }, + { + id: "cloud-providers", + name: "Cloud Providers", + pages: [ + { id: "aws", name: "AWS" }, + { id: "azure", name: "Azure" }, + { id: "gcp", name: "GCP" }, + ], + }, + { + id: "administration", + name: "Administration", + pages: [ + { id: "performance", name: "Performance" }, + { id: "auth", name: "Auth" }, + { id: "observability", name: "Observability" }, + { id: "migration", name: "Migration" }, + ], + }, + ], + }, + { + id: "integrations", + name: "Integrations", + default: "chroma-integrations", + icon: BlocksIcon, + pages: [{ id: "chroma-integrations", name: "Chroma Integrations" }], + subsections: [ + { + id: "embedding-models", + name: "Embedding Models", + generatePages: true, + }, + { + id: "frameworks", + name: "Frameworks", + generatePages: true, + }, + ], + }, + { + id: "cli", + name: "CLI", + default: "install-and-run", + icon: SquareTerminalIcon, + pages: [ + { id: "install-and-run", name: "Install and run" }, + { id: "vacuum", name: "Vacuum" }, + ], + }, + { + id: "reference", + name: "Reference", + icon: WrenchIcon, + default: "chroma-reference", + pages: [{ id: "chroma-reference", name: "Chroma Reference" }], + subsections: [ + { + id: "python", + name: "Python", + pages: [ + { id: "client", name: "Client" }, + { id: "collection", name: "Collection" }, + ], + }, + { + id: "js", + name: "JavaScript/Typescript", + pages: [ + { id: "client", name: "Client" }, + { id: "collection", name: "Collection" }, + ], + }, + ], + }, + { + id: "guides-and-examples", + name: "Guides & Examples", + icon: GraduationCap, + comingSoon: true, + }, +]; + +export default sidebarConfig; diff --git a/docs/docs.trychroma.com/markdoc/functions.ts b/docs/docs.trychroma.com/markdoc/functions.ts deleted file mode 100644 index 76794fed3a8..00000000000 --- a/docs/docs.trychroma.com/markdoc/functions.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* Use this file to export your Markdoc functions */ - -export const includes = { - transform(parameters) { - const [array, value] = Object.values(parameters); - - return Array.isArray(array) ? array.includes(value) : false; - }, -}; - -export const upper = { - transform(parameters) { - const string = parameters[0]; - return typeof string === 'string' ? string.toUpperCase() : string; - }, -}; diff --git a/docs/docs.trychroma.com/markdoc/nodes/fence.markdoc.tsx b/docs/docs.trychroma.com/markdoc/nodes/fence.markdoc.tsx deleted file mode 100644 index 5d8d5e68d6d..00000000000 --- a/docs/docs.trychroma.com/markdoc/nodes/fence.markdoc.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import {Tag, nodes} from '@markdoc/markdoc'; -import {CodeBlock} from '../../components/CodeBlock'; - -export const fence = { - render: CodeBlock, - attributes: { - filename: { - type: String, - }, - codetab: { - type: Boolean - }, - ...nodes.fence.attributes, - }, - transform(node, config) { - const attributes = node.transformAttributes(config); - const {language} = node.children[0].attributes; - const content = node.attributes.content; - return new Tag(this.render, {...attributes, language}, [content]); - }, -}; diff --git a/docs/docs.trychroma.com/markdoc/nodes/heading.markdoc.ts b/docs/docs.trychroma.com/markdoc/nodes/heading.markdoc.ts deleted file mode 100644 index 81bff9851f5..00000000000 --- a/docs/docs.trychroma.com/markdoc/nodes/heading.markdoc.ts +++ /dev/null @@ -1,31 +0,0 @@ -import {Tag} from '@markdoc/markdoc'; -import {Heading} from '../../components/markdoc/Heading'; - -function generateID(children, attributes) { - if (attributes.id && typeof attributes.id === 'string') { - return attributes.id; - } - return children - .filter((child) => typeof child === 'string') - .join(' ') - .replace(/[?]/g, '') - .replace(/\s+/g, '-') - .toLowerCase(); -} - -export const heading = { - render: Heading, - children: ['inline'], - attributes: { - id: {type: String}, - level: {type: Number, required: true, default: 1}, - className: {type: String}, - }, - transform(node, config) { - const attributes = node.transformAttributes(config); - const children = node.transformChildren(config); - const id = generateID(children, attributes); - - return new Tag(this.render, {...attributes, id}, children); - }, -}; diff --git a/docs/docs.trychroma.com/markdoc/nodes/index.ts b/docs/docs.trychroma.com/markdoc/nodes/index.ts deleted file mode 100644 index 321c47e7461..00000000000 --- a/docs/docs.trychroma.com/markdoc/nodes/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -/* Use this file to export your markdoc nodes */ -export * from './fence.markdoc'; -export * from './heading.markdoc'; -export * from './link.markdoc'; diff --git a/docs/docs.trychroma.com/markdoc/nodes/link.markdoc.ts b/docs/docs.trychroma.com/markdoc/nodes/link.markdoc.ts deleted file mode 100644 index 45a7d5146f1..00000000000 --- a/docs/docs.trychroma.com/markdoc/nodes/link.markdoc.ts +++ /dev/null @@ -1,9 +0,0 @@ -// @ts-expect-error markdocs doesn't yet expose this properly -import { link as NextLink } from '@markdoc/next.js/tags'; - -import { AppLink } from '../../components/markdoc/AppLink'; - -export const link = { - ...NextLink, - render: AppLink -}; diff --git a/docs/docs.trychroma.com/markdoc/partials/header.md b/docs/docs.trychroma.com/markdoc/partials/header.md deleted file mode 100644 index a217deb5c3c..00000000000 --- a/docs/docs.trychroma.com/markdoc/partials/header.md +++ /dev/null @@ -1 +0,0 @@ -# Chroma Docs diff --git a/docs/docs.trychroma.com/markdoc/tags/codetabs.markdoc.ts b/docs/docs.trychroma.com/markdoc/tags/codetabs.markdoc.ts deleted file mode 100644 index 70f6c5166fb..00000000000 --- a/docs/docs.trychroma.com/markdoc/tags/codetabs.markdoc.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { Tag } from '@markdoc/markdoc'; -import { CodeTabs } from '../../components/markdoc/CodeTabs'; -import { CodeTab } from '../../components/markdoc/CodeTab'; -// import { CodeBlock } from '../../components/CodeBlock'; - -export const codetabs = { - render: CodeTabs, - attributes: { - group: { - type: String - }, - customHeader: { - type: String - } - }, - transform(node, config) { - const attributes = node.transformAttributes(config); - const labels = node - .transformChildren(config) - .filter((child) => child && child.name === 'Codetab') - .map((tab) => (typeof tab === 'object' ? tab.attributes.label : null)); - - return new Tag(this.render, { ...attributes, labels }, node.transformChildren(config)); - } -}; - -export const codetab = { - render: CodeTab, - attributes: { - label: { - type: String - }, - } -}; diff --git a/docs/docs.trychroma.com/markdoc/tags/index.ts b/docs/docs.trychroma.com/markdoc/tags/index.ts deleted file mode 100644 index 1fb87a54375..00000000000 --- a/docs/docs.trychroma.com/markdoc/tags/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -/* Use this file to export your markdoc tags */ -export * from './tabs.markdoc' -export {note, br, math} from './note.markdoc'; -export {special_table} from './special_table.markdoc'; -export {codetabs, codetab} from './codetabs.markdoc'; diff --git a/docs/docs.trychroma.com/markdoc/tags/note.markdoc.ts b/docs/docs.trychroma.com/markdoc/tags/note.markdoc.ts deleted file mode 100644 index 912001b5074..00000000000 --- a/docs/docs.trychroma.com/markdoc/tags/note.markdoc.ts +++ /dev/null @@ -1,28 +0,0 @@ -import MathComponent from "../../components/markdoc/Math"; -import { Note } from "../../components/markdoc/Note"; -import { Br } from "../../components/markdoc/misc"; - -export const note = { - render: Note, - attributes: { - type: { - type: String - }, - title: { - type: String - }, - } -}; - -export const br = { - render: Br, -}; - -export const math = { - render: MathComponent, - attributes: { - latexText: { - type: String - }, - } -}; diff --git a/docs/docs.trychroma.com/markdoc/tags/special_table.markdoc.ts b/docs/docs.trychroma.com/markdoc/tags/special_table.markdoc.ts deleted file mode 100644 index 647c390655a..00000000000 --- a/docs/docs.trychroma.com/markdoc/tags/special_table.markdoc.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { SpecialTable } from "../../components/markdoc/SpecialTable"; - -export const special_table = { - render: SpecialTable, - attributes: { - label: { - type: String - }, - } - }; diff --git a/docs/docs.trychroma.com/markdoc/tags/tabs.markdoc.ts b/docs/docs.trychroma.com/markdoc/tags/tabs.markdoc.ts deleted file mode 100644 index 1765829866b..00000000000 --- a/docs/docs.trychroma.com/markdoc/tags/tabs.markdoc.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { Tag } from '@markdoc/markdoc'; -import { Tabs } from '../../components/markdoc/Tabs'; -import { Tab } from '../../components/markdoc/Tab'; - -export const tabs = { - render: Tabs, - attributes: { - group: { - type: String - }, - hideTabs: { - type: Boolean - }, - hideContent: { - type: Boolean - } - }, - transform(node, config) { - const attributes = node.transformAttributes(config); - const labels = node - .transformChildren(config) - .filter((child) => child && child.name === 'Tab') - .map((tab) => (typeof tab === 'object' ? tab.attributes.label : null)); - - return new Tag(this.render, { ...attributes, labels }, node.transformChildren(config)); - } -}; - -export const tab = { - render: Tab, - attributes: { - label: { - type: String - }, - } -}; diff --git a/docs/docs.trychroma.com/middleware.ts b/docs/docs.trychroma.com/middleware.ts new file mode 100644 index 00000000000..96e27a4411c --- /dev/null +++ b/docs/docs.trychroma.com/middleware.ts @@ -0,0 +1,59 @@ +import { NextRequest, NextResponse } from "next/server"; + +const legacyPathsMapping: Record = { + "/getting-started": "/docs/overview/getting-started", + "/guides": "/docs/run-chroma/ephemeral-client", + "/guides/embeddings": "/docs/embeddings/embedding-functions", + "/guides/multimodal": "/docs/embeddings/multimodal", + "/integrations": "/integrations/chroma-integrations", + "/integrations/openai": "/integrations/embedding-models/openai", + "/integrations/cohere": "/integrations/embedding-models/cohere", + "/integrations/google-gemini": "/integrations/embedding-models/google-gemini", + "/integrations/hugging-face-server": + "/integrations/embedding-models/hugging-face-server", + "/integrations/hugging-face": "/integrations/embedding-models/hugging-face", + "/integrations/instructor": "/integrations/embedding-models/instructor", + "/integrations/jinaai": "/integrations/embedding-models/jina-ai", + "/integrations/ollama": "/integrations/embedding-models/ollama", + "/integrations/roboflow": "/integrations/embedding-models/roboflow", + "/integrations/langchain": "/integrations/frameworks/langchain", + "/integrations/llamaindex": "/integrations/frameworks/llamaindex", + "/integrations/braintrust": "/integrations/frameworks/braintrust", + "/integrations/haystack": "/integrations/frameworks/haystack", + "/integrations/openllmetry": "/integrations/frameworks/openllmetry", + "/integrations/streamlit": "/integrations/frameworks/streamlit", + "/integrations/openlit": "/integrations/frameworks/openlit", + "/deployment": "/production/deployment", + "/deployment/client-server-mode": + "/production/chroma-server/client-server-mode", + "/deployment/thin-client": "/production/chroma-server/python-thin-client", + "/deployment/docker": "/production/containers/docker", + "/deployment/aws": "/production/cloud-providers/aws", + "/deployment/azure": "/production/cloud-providers/azure", + "/deployment/gcp": "/production/cloud-providers/gcp", + "/deployment/performance": "/production/administration/performance", + "/deployment/observability": "/production/administration/observability", + "/deployment/migration": "/production/administration/migration", + "/deployment/auth": "/production/administration/auth", + "/telemetry": "/docs/overview/telemetry", + "/roadmap": "/docs/overview/roadmap", + "/contributing": "/docs/overview/contributing", + "/about": "/docs/overview/about", + "/reference": "/reference/chroma-reference", + "/reference/py-client": "/reference/python/client", + "/reference/py-collection": "/reference/python/collection", + "/reference/js-client": "/reference/js/client", + "/reference/js-collection": "/reference/js/collection", + "/reference/cli": "/cli/run", +}; + +export const middleware = (request: NextRequest) => { + const path = request.nextUrl.pathname; + + if (path in legacyPathsMapping) { + const currentPath = legacyPathsMapping[path]; + return NextResponse.redirect(new URL(currentPath, request.url)); + } + + return NextResponse.next(); +}; diff --git a/docs/docs.trychroma.com/next-env.d.ts b/docs/docs.trychroma.com/next-env.d.ts index a4a7b3f5cfa..40c3d68096c 100644 --- a/docs/docs.trychroma.com/next-env.d.ts +++ b/docs/docs.trychroma.com/next-env.d.ts @@ -2,4 +2,4 @@ /// // NOTE: This file should not be edited -// see https://nextjs.org/docs/pages/building-your-application/configuring/typescript for more information. +// see https://nextjs.org/docs/app/building-your-application/configuring/typescript for more information. diff --git a/docs/docs.trychroma.com/next.config.js b/docs/docs.trychroma.com/next.config.js deleted file mode 100644 index 32db6416d53..00000000000 --- a/docs/docs.trychroma.com/next.config.js +++ /dev/null @@ -1,6 +0,0 @@ -const withMarkdoc = require('@markdoc/next.js'); - -module.exports = - withMarkdoc(/* config: https://markdoc.io/docs/nextjs#options */)({ - pageExtensions: ['jsx', 'ts', 'tsx', 'md', 'mdoc'], - }); diff --git a/docs/docs.trychroma.com/next.config.mjs b/docs/docs.trychroma.com/next.config.mjs new file mode 100644 index 00000000000..9aca8484266 --- /dev/null +++ b/docs/docs.trychroma.com/next.config.mjs @@ -0,0 +1,19 @@ +/** @type {import('next').NextConfig} */ +const nextConfig = { + webpack(config) { + config.module.rules.push({ + test: /\.svg$/, + use: [ + { + loader: "@svgr/webpack", + options: { + icon: true, + }, + }, + ], + }); + return config; + } +}; + +export default nextConfig; diff --git a/docs/docs.trychroma.com/package.json b/docs/docs.trychroma.com/package.json index 11c60476db9..b19d75c6cf5 100644 --- a/docs/docs.trychroma.com/package.json +++ b/docs/docs.trychroma.com/package.json @@ -9,10 +9,12 @@ "gen-python": "sh scripts/pythonDocs.sh" }, "dependencies": { - "@docsearch/react": "^3.6.0", + "@docsearch/react": "^3.8.0", + "@heroicons/react": "^2.2.0", "@markdoc/markdoc": "latest", "@markdoc/next.js": "^0.3.7", "@matejmazur/react-katex": "^3.1.3", + "@radix-ui/react-dialog": "^1.1.2", "@radix-ui/react-dropdown-menu": "^2.0.6", "@radix-ui/react-icons": "^1.3.0", "@radix-ui/react-menubar": "^1.0.4", @@ -23,28 +25,46 @@ "@radix-ui/react-toast": "^1.1.5", "@radix-ui/react-tooltip": "^1.0.7", "@sindresorhus/slugify": "^2.2.1", + "@svgr/webpack": "^8.1.0", + "@tailwindcss/typography": "^0.5.15", + "algoliasearch": "^5.17.1", "class-variance-authority": "^0.7.0", "clsx": "^2.1.0", "flexsearch": "^0.7.43", + "gray-matter": "^4.0.3", + "image-size": "^1.1.1", "katex": "^0.16.9", - "next": "latest", + "lucide": "^0.464.0", + "lucide-react": "^0.464.0", + "next": "^14.2.13", "next-themes": "^0.3.0", - "posthog-js": "^1.131.4", + "posthog-js": "^1.200.1", "prismjs": "^1.29.0", - "react": "latest", - "react-dom": "latest", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "rehype-highlight": "^7.0.1", + "rehype-stringify": "^10.0.1", + "remark-parse": "^11.0.0", + "remark-rehype": "^11.1.1", + "shadcn": "^2.1.6", "tailwind-merge": "^2.2.1", - "tailwindcss-animate": "^1.0.7" + "tailwindcss-animate": "^1.0.7", + "unified": "^11.0.5", + "vaul": "^1.1.1" }, "devDependencies": { + "@types/katex": "^0.16.7", "@types/node": "latest", + "@types/prismjs": "^1.26.5", "@types/react": "latest", "@types/react-dom": "latest", "autoprefixer": "^10.4.18", + "eslint-config-next": "^15.0.3", "postcss": "^8.4.35", + "prettier": "^3.4.1", "tailwindcss": "^3.4.1", - "typescript": "latest", "typedoc": "^0.24.7", - "typedoc-plugin-markdown": "^3.15.3" + "typedoc-plugin-markdown": "^3.15.3", + "typescript": "latest" } } diff --git a/docs/docs.trychroma.com/pages/_app.tsx b/docs/docs.trychroma.com/pages/_app.tsx deleted file mode 100644 index 2b3cb657736..00000000000 --- a/docs/docs.trychroma.com/pages/_app.tsx +++ /dev/null @@ -1,256 +0,0 @@ -import React, { createContext, useContext, useEffect, useState } from 'react'; -import Head from 'next/head'; -import Link from 'next/link'; -import { GlobalStateContext, GlobalStateProvider } from '../components/layout/state'; - -import posthog from 'posthog-js' -import { PostHogProvider } from 'posthog-js/react' - -// Check that PostHog is client-side (used to handle Next.js SSR) -if (typeof window !== 'undefined') { - posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY, { - api_host: process.env.NEXT_PUBLIC_POSTHOG_HOST || "https://us.i.posthog.com", - // Enable debug mode in development - loaded: (posthog) => { - if (process.env.NODE_ENV === 'development') posthog.debug() - } - }) -} - -import {TopNav} from '../components/layout/TopNav'; -import {SideNav} from '../components/layout/SideNav'; -import {TableOfContents} from '../components/layout/TableOfContents'; - -import { ThemeProvider } from 'next-themes' - -import '../public/globals.css' -import 'katex/dist/katex.min.css'; - -import type { AppProps } from 'next/app' -import type { MarkdocNextJsPageProps } from '@markdoc/next.js' - -import { Inter, IBM_Plex_Mono } from 'next/font/google' -// import IBM Plex Mono -import { Toaster } from "../components/ui/toaster" -import { Icons } from '../components/ui/icons'; -import { ThemeToggle } from '../components/ui/toggle-theme'; -import { Breadcrumb, BreadcrumbList, BreadcrumbItem, BreadcrumbLink, BreadcrumbSeparator, BreadcrumbPage } from '../components/ui/breadcrumb'; -import { useRouter } from 'next/router'; - -const inter = Inter({ - subsets: ['latin'], - display: 'swap', - variable: '--font-inter', -}) - -const ibmPlexMono = IBM_Plex_Mono({ - subsets: ['latin'], - display: 'swap', - weight: "400", - variable: '--font-ibm-plex-mono', -}) - -const TITLE = 'Chroma Docs'; -const DESCRIPTION = 'Chroma is the open-source AI application database. Batteries included.'; - -function collectHeadings(node, sections = []) { - if (node) { - if (node.name === 'Heading') { - const title = node.children[0]; - - if (typeof title === 'string') { - sections.push({ - ...node.attributes, - title - }); - } - } - - if (node.children) { - for (const child of node.children) { - collectHeadings(child, sections); - } - } - } - - return sections; -} - -const ROOT_ITEMS = require(`./_sidenav.js`).items; - -export type ChromaDocsProps = MarkdocNextJsPageProps - -export default function ChromaDocs({ Component, pageProps }: AppProps) { - const { markdoc } = pageProps; - - const router = useRouter() - - useEffect(() => { - // Track page views - const handleRouteChange = () => posthog?.capture('$pageview') - router.events.on('routeChangeComplete', handleRouteChange) - - return () => { - router.events.off('routeChangeComplete', handleRouteChange) - } - }, []) - - let title = TITLE; - let description = DESCRIPTION; - if (markdoc && (markdoc.frontmatter !== undefined)) { - if (markdoc.frontmatter.title) { - title = markdoc.frontmatter.title; - } - if (markdoc.frontmatter.description) { - description = markdoc.frontmatter.description; - } - } - - const toc = pageProps.markdoc?.content - ? collectHeadings(pageProps.markdoc.content) - : []; - - // get the pathname and figure out if we are in a group or not - // this requires iterating through ROOT_ITEMS - const pathname = router.pathname; - let pathVar = router.asPath.split('/')[1] !== undefined ? router.asPath.split('/')[1] : ''; - let inGroup = false - let groupObject = null - // iterate through ROOT_ITEMS to see if pathVar is a group or not - ROOT_ITEMS.map((item: any) => { - if (item.href === `/${pathVar}` && item.type === 'group') { - inGroup = true - groupObject = item - } - }) - - // if inGroup is true, then we need to build the breadcrumbs - let breadcrumbs = [] - if (inGroup) { - breadcrumbs.push({href: `/${pathVar}`, name: groupObject.title}) - } - // if markdoc.frontmatter.title does not equal the groupObject.title, then we need to add it to our breadcrumbs - // if the route is more than 1 level deep - if (router.pathname.split('/').length > 2) { - if (inGroup && (markdoc.frontmatter !== undefined) && markdoc.frontmatter.title !== groupObject.title) { - breadcrumbs.push({href: `/${pathVar}/${markdoc.frontmatter.title}`, name: markdoc.frontmatter.title}) - } - } - - const pageTitle = `${title}${title !== "Chroma" ? " | Chroma Docs": " Docs" }` - - // generate the github edit link - let filePath = router.asPath.split('/').slice(1).join('/') - - // if root, then index.md - if (filePath === '') { - filePath = 'index' - } - - // if inGroup but .slice(2) is empty, then add index.md - if (inGroup && router.asPath.split('/').slice(1)[1] === undefined) { - filePath = filePath + '/index' - } - - let githubEditLink = `https://github.com/chroma-core/chroma/blob/main/docs/docs.trychroma.com/pages/` + filePath + '.md' - - return ( - - -
- - - {pageTitle} - - - - - - - - - - - - - - - - - - - - -
-
-
- -
-
- -
- - {inGroup? ( - - - - Home - - - {breadcrumbs.map((item, index) => { - return ( - <> - - {item.name} - - {/* if not the last item, add a BreadcrumbSeparator */} - {index !== breadcrumbs.length - 1 ? ( - - ) : ( - <> - )} - - ) - })} - - - - ) : <> } - -
{title}
- - -
- -
-
- -
-
- -
- -
- -
-
-
- ); -} diff --git a/docs/docs.trychroma.com/pages/_sidenav.js b/docs/docs.trychroma.com/pages/_sidenav.js deleted file mode 100644 index 1c344055e4c..00000000000 --- a/docs/docs.trychroma.com/pages/_sidenav.js +++ /dev/null @@ -1,16 +0,0 @@ -export const items = [ - {href: '/', title: '🏡 Home'}, - {href: '/getting-started', title: '🔑 Getting Started'}, - // {href: '/examples', title: '💡 Examples', type: 'group'}, - {href: '/guides', title: '🧪 Guides', type: 'group'}, - {href: '/integrations', title: '🔌 Integrations', type: 'group'}, - {href: '/deployment', title: '☁️ Deployment', type: 'group'}, - {href: '/telemetry', title: '📏 Telemetry'}, - {href: '/roadmap', title: '🛣️ Roadmap'}, - // {href: '/cloud', title: '☁️ Cloud', type: 'group'}, - // {href: '/community', title: '🌎 Community'}, - {href: '/contributing', title: '🍻 Contributing'}, - {href: '/troubleshooting', title: '🔍 Troubleshooting'}, - {href: '/about', title: '👽 About'}, - {href: '/reference', title: '🔧 Reference', type: 'group'}, - ]; diff --git a/docs/docs.trychroma.com/pages/cloud/_sidenav.js b/docs/docs.trychroma.com/pages/cloud/_sidenav.js deleted file mode 100644 index aeb47895ff1..00000000000 --- a/docs/docs.trychroma.com/pages/cloud/_sidenav.js +++ /dev/null @@ -1,11 +0,0 @@ - -export const items = [ - { - title: 'Cloud', - links: [ - { href: '/cloud/teams', children: 'Teams' }, - { href: '/cloud/apikeys', children: 'API Keys' }, - { href: '/cloud/performance', children: 'Performance' }, - ] - }, - ]; diff --git a/docs/docs.trychroma.com/pages/cloud/apikeys.md b/docs/docs.trychroma.com/pages/cloud/apikeys.md deleted file mode 100644 index ae754986351..00000000000 --- a/docs/docs.trychroma.com/pages/cloud/apikeys.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -title: API Keys ---- diff --git a/docs/docs.trychroma.com/pages/cloud/index.md b/docs/docs.trychroma.com/pages/cloud/index.md deleted file mode 100644 index 029fd147caa..00000000000 --- a/docs/docs.trychroma.com/pages/cloud/index.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -title: Chroma Cloud ---- diff --git a/docs/docs.trychroma.com/pages/cloud/performance.md b/docs/docs.trychroma.com/pages/cloud/performance.md deleted file mode 100644 index 609b952fe5c..00000000000 --- a/docs/docs.trychroma.com/pages/cloud/performance.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -title: Performance ---- diff --git a/docs/docs.trychroma.com/pages/cloud/teams.md b/docs/docs.trychroma.com/pages/cloud/teams.md deleted file mode 100644 index 2905bfbd6a5..00000000000 --- a/docs/docs.trychroma.com/pages/cloud/teams.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -title: Teams ---- diff --git a/docs/docs.trychroma.com/pages/community.md b/docs/docs.trychroma.com/pages/community.md deleted file mode 100644 index e0dc0012b1c..00000000000 --- a/docs/docs.trychroma.com/pages/community.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -title: 🌎 Community ---- diff --git a/docs/docs.trychroma.com/pages/deployment/_sidenav.js b/docs/docs.trychroma.com/pages/deployment/_sidenav.js deleted file mode 100644 index 4fb5193104f..00000000000 --- a/docs/docs.trychroma.com/pages/deployment/_sidenav.js +++ /dev/null @@ -1,46 +0,0 @@ -export const items = [ - // { - // title: 'Runtimes', - // links: [ - // { href: '/deployment/in-memory', children: 'In-memory' }, - // { href: '/deployment/persistent-client', children: 'Persistent' }, - // { href: '/deployment/docker', children: 'Docker' }, - // { href: '/deployment/kubernetes', children: 'Kubernetes' }, - // ] - // }, - { - title: "Chroma Server", - links: [ - { - href: "/deployment/client-server-mode", - children: "Client/Server Mode", - }, - { href: "/deployment/thin-client", children: "Python Thin-Client" }, - ], - }, - { - title: "Containers", - links: [{ href: "/deployment/docker", children: "Docker" }], - }, - { - title: "Cloud Providers", - links: [ - { href: "/deployment/aws", children: "AWS" }, - { href: "/deployment/azure", children: "Azure" }, - { href: "/deployment/gcp", children: "GCP" }, - ], - }, - { - title: "Administration", - links: [ - { href: "/deployment/performance", children: "🚀 Performance" }, - // { href: '/deployment/logging', children: 'Logging' }, - { href: "/deployment/observability", children: "👀 Observability" }, - { href: "/deployment/migration", children: "✈️ Migration" }, - // { href: '/deployment/security', children: 'Security' }, - // { href: '/deployment/encryption', children: 'Encryption' }, - { href: "/deployment/auth", children: "🔒 Auth" }, - // { href: '/deployment/performance', children: 'Performance' }, - ], - }, -]; diff --git a/docs/docs.trychroma.com/pages/deployment/encryption.md b/docs/docs.trychroma.com/pages/deployment/encryption.md deleted file mode 100644 index 347cfdd854b..00000000000 --- a/docs/docs.trychroma.com/pages/deployment/encryption.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -title: Encryption ---- diff --git a/docs/docs.trychroma.com/pages/deployment/in-memory.md b/docs/docs.trychroma.com/pages/deployment/in-memory.md deleted file mode 100644 index 5db5e7da17f..00000000000 --- a/docs/docs.trychroma.com/pages/deployment/in-memory.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -title: In-memory ---- diff --git a/docs/docs.trychroma.com/pages/deployment/kubernetes.md b/docs/docs.trychroma.com/pages/deployment/kubernetes.md deleted file mode 100644 index cd640f053a7..00000000000 --- a/docs/docs.trychroma.com/pages/deployment/kubernetes.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -title: Kubernetes ---- diff --git a/docs/docs.trychroma.com/pages/deployment/logging.md b/docs/docs.trychroma.com/pages/deployment/logging.md deleted file mode 100644 index 78563e8b184..00000000000 --- a/docs/docs.trychroma.com/pages/deployment/logging.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -title: Logging ---- diff --git a/docs/docs.trychroma.com/pages/deployment/persistent-client.md b/docs/docs.trychroma.com/pages/deployment/persistent-client.md deleted file mode 100644 index 3598c7304c1..00000000000 --- a/docs/docs.trychroma.com/pages/deployment/persistent-client.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -title: Persistent Client ---- diff --git a/docs/docs.trychroma.com/pages/deployment/security.md b/docs/docs.trychroma.com/pages/deployment/security.md deleted file mode 100644 index 77350687f54..00000000000 --- a/docs/docs.trychroma.com/pages/deployment/security.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -title: Security ---- diff --git a/docs/docs.trychroma.com/pages/docs/index.md b/docs/docs.trychroma.com/pages/docs/index.md deleted file mode 100644 index 7137deb37d0..00000000000 --- a/docs/docs.trychroma.com/pages/docs/index.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -title: Overview ---- diff --git a/docs/docs.trychroma.com/pages/examples/_sidenav.js b/docs/docs.trychroma.com/pages/examples/_sidenav.js deleted file mode 100644 index cd2161d28af..00000000000 --- a/docs/docs.trychroma.com/pages/examples/_sidenav.js +++ /dev/null @@ -1,20 +0,0 @@ -export const items = [ - { - title: 'Examples', - links: [ - // { href: '/examples/documents', children: 'Q&A over Documents' }, - // { href: '/examples/code', children: 'Q&A over Code' }, - { href: '/examples/multimodal', children: '🖼️ Multimodal' }, - // { href: '/examples/agents', children: 'Agents' }, - ] - }, - // { - // title: 'Frameworks', - // links: [ - // { href: '/examples/nextjs', children: 'NextJS' }, - // { href: '/examples/rails', children: 'Rails' }, - // { href: '/examples/fastapi', children: 'FastAPI' }, - // ] - // }, - - ]; diff --git a/docs/docs.trychroma.com/pages/examples/agents.md b/docs/docs.trychroma.com/pages/examples/agents.md deleted file mode 100644 index 20f4638fe80..00000000000 --- a/docs/docs.trychroma.com/pages/examples/agents.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -title: Agents ---- diff --git a/docs/docs.trychroma.com/pages/examples/code.md b/docs/docs.trychroma.com/pages/examples/code.md deleted file mode 100644 index 14cdff72057..00000000000 --- a/docs/docs.trychroma.com/pages/examples/code.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -title: Q&A over Code ---- diff --git a/docs/docs.trychroma.com/pages/examples/documents.md b/docs/docs.trychroma.com/pages/examples/documents.md deleted file mode 100644 index 00b145cca1a..00000000000 --- a/docs/docs.trychroma.com/pages/examples/documents.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -title: Q&A over Documents ---- diff --git a/docs/docs.trychroma.com/pages/examples/fastapi.md b/docs/docs.trychroma.com/pages/examples/fastapi.md deleted file mode 100644 index ca88f5abfd3..00000000000 --- a/docs/docs.trychroma.com/pages/examples/fastapi.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -title: FastAPI ---- diff --git a/docs/docs.trychroma.com/pages/examples/index.md b/docs/docs.trychroma.com/pages/examples/index.md deleted file mode 100644 index 66915ad0a4d..00000000000 --- a/docs/docs.trychroma.com/pages/examples/index.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -title: 💡 Examples ---- - -This section contains a growing set of examples. - -Examples listed here are 1st class citizens in the documentation. They are tested, maintained and updated as the library evolves. Walkthroughs are designed to go step by step. - - -{% special_table %} -{% /special_table %} - -| | | Python | JS | -|--------------|-----------|---------------|--| -| [🖼️ Multimodal](/examples/multimodal) | Embed and retrieve images | ✅ | ➖ | -| 🚧 *More Coming Soon* | | | | diff --git a/docs/docs.trychroma.com/pages/examples/nextjs.md b/docs/docs.trychroma.com/pages/examples/nextjs.md deleted file mode 100644 index edda2c4a4e8..00000000000 --- a/docs/docs.trychroma.com/pages/examples/nextjs.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -title: NextJS ---- diff --git a/docs/docs.trychroma.com/pages/examples/rails.md b/docs/docs.trychroma.com/pages/examples/rails.md deleted file mode 100644 index 78a34a78b47..00000000000 --- a/docs/docs.trychroma.com/pages/examples/rails.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -title: Rails ---- diff --git a/docs/docs.trychroma.com/pages/getting-started.md b/docs/docs.trychroma.com/pages/getting-started.md deleted file mode 100644 index 8bc3cad1f9f..00000000000 --- a/docs/docs.trychroma.com/pages/getting-started.md +++ /dev/null @@ -1,326 +0,0 @@ ---- -title: "🔑 Getting Started" ---- - -{% tabs group="code-lang" hideContent=true %} - -{% tab label="Python" %} -{% /tab %} - -{% tab label="Javascript" %} -{% /tab %} - -{% /tabs %} - -Chroma is an AI-native open-source vector database. It comes with everything you need to get started built in, and runs on your machine. A [hosted version](https://airtable.com/shrOAiDUtS2ILy5vZ) is in early access! - -### 1. Install - -{% tabs group="code-lang" hideTabs=true %} -{% tab label="Python" %} - -```bash -pip install chromadb # [!code $] -``` - -{% /tab %} -{% tab label="Javascript" %} - -{% codetabs customHeader="sh" %} -{% codetab label="yarn" %} - -```bash {% codetab=true %} -yarn add chromadb chromadb-default-embed # [!code $] -``` - -{% /codetab %} -{% codetab label="npm" %} - -```bash {% codetab=true %} -npm install --save chromadb chromadb-default-embed # [!code $] -``` - -{% /codetab %} -{% codetab label="pnpm" %} - -```bash {% codetab=true %} -pnpm add chromadb chromadb-default-embed # [!code $] -``` - -{% /codetab %} -{% /codetabs %} - -Install chroma via `pypi` to easily run the backend server. ([Docker](./deployment/docker) also available) - -```bash -pip install chromadb # [!code $] -``` - -{% /tab %} -{% /tabs %} - -### 2. Create a Chroma Client - -{% tabs group="code-lang" hideTabs=true %} -{% tab label="Python" %} - -```python -import chromadb -chroma_client = chromadb.Client() -``` - -{% /tab %} -{% tab label="Javascript" %} - -Run the Chroma backend: - -{% codetabs customHeader="sh" %} -{% codetab label="CLI" %} - -```bash {% codetab=true %} -chroma run --path ./getting-started # [!code $] -``` - -{% /codetab %} -{% codetab label="Docker" %} - -```bash {% codetab=true %} -docker pull chromadb/chroma # [!code $] -docker run -p 8000:8000 chromadb/chroma # [!code $] -``` - -{% /codetab %} -{% /codetabs %} - -Then create a client which connects to it: - -{% codetabs customHeader="js" %} -{% codetab label="ESM" %} - -```js {% codetab=true %} -import { ChromaClient } from "chromadb"; -const client = new ChromaClient(); -``` - -{% /codetab %} -{% codetab label="CJS" %} - -```js {% codetab=true %} -const { ChromaClient } = require("chromadb"); -const client = new ChromaClient(); -``` - -{% /codetab %} -{% /codetabs %} - -{% /tab %} - -{% /tabs %} - -### 3. Create a collection - -Collections are where you'll store your embeddings, documents, and any additional metadata. You can create a collection with a name: - -{% tabs group="code-lang" hideTabs=true %} -{% tab label="Python" %} - -```python -collection = chroma_client.create_collection(name="my_collection") -``` - -{% /tab %} -{% tab label="Javascript" %} - -```js -const collection = await client.createCollection({ - name: "my_collection", -}); -``` - -{% /tab %} - -{% /tabs %} - -### 4. Add some text documents to the collection - -Chroma will store your text and handle embedding and indexing automatically. You can also customize the embedding model. - -{% tabs group="code-lang" hideTabs=true %} -{% tab label="Python" %} - -```python -collection.add( - documents=[ - "This is a document about pineapple", - "This is a document about oranges" - ], - ids=["id1", "id2"] -) -``` - -{% /tab %} -{% tab label="Javascript" %} - -```js -await collection.add({ - documents: [ - "This is a document about pineapple", - "This is a document about oranges", - ], - ids: ["id1", "id2"], -}); -``` - -{% /tab %} - -{% /tabs %} - -### 5. Query the collection - -You can query the collection with a list of query texts, and Chroma will return the `n` most similar results. It's that easy! - -{% tabs group="code-lang" hideTabs=true %} -{% tab label="Python" %} - -```python -results = collection.query( - query_texts=["This is a query document about hawaii"], # Chroma will embed this for you - n_results=2 # how many results to return -) -print(results) -``` - -{% /tab %} -{% tab label="Javascript" %} - -```js -const results = await collection.query({ - queryTexts: "This is a query document about hawaii", // Chroma will embed this for you - nResults: 2, // how many results to return -}); - -console.log(results); -``` - -{% /tab %} - -{% /tabs %} - -### 6. Inspect Results - -From the above query - you can see that our query about `hawaii` is the semantically most similar to the document about `pineapple`. This, intuitively, makes sense! - -{% tabs group="code-lang" hideTabs=true %} -{% tab label="Python" %} - -```python -{ - 'documents': [[ - 'This is a document about pineapple', - 'This is a document about oranges' - ]], - 'ids': [['id1', 'id2']], - 'distances': [[1.0404009819030762, 1.243080496788025]], - 'uris': None, - 'data': None, - 'metadatas': [[None, None]], - 'embeddings': None, -} -``` - -{% /tab %} -{% tab label="Javascript" %} - -```js -{ - 'documents': [[ - 'This is a document about pineapple', - 'This is a document about oranges' - ]], - 'ids': [['id1', 'id2']], - 'distances': [[1.0404009819030762, 1.243080496788025]], - 'uris': null, - 'data': null, - 'metadatas': [[null, null]], - 'embeddings': null, -} -``` - -{% /tab %} - -{% /tabs %} - -### 7. Try it out yourself - -For example - what if we tried querying with `"This is a document about florida"`? - -{% tabs group="code-lang" hideTabs=true %} -{% tab label="Python" %} - -```py -import chromadb -chroma_client = chromadb.Client() - -# switch `create_collection` to `get_or_create_collection` to avoid creating a new collection every time -collection = chroma_client.get_or_create_collection(name="my_collection") - -# switch `add` to `upsert` to avoid adding the same documents every time -collection.upsert( - documents=[ - "This is a document about pineapple", - "This is a document about oranges" - ], - ids=["id1", "id2"] -) - -results = collection.query( - query_texts=["This is a query document about florida"], # Chroma will embed this for you - n_results=2 # how many results to return -) - -print(results) -``` - -{% /tab %} -{% tab label="Javascript" %} - -```js -import { ChromaClient } from "chromadb"; -const client = new ChromaClient(); - -// switch `createCollection` to `getOrCreateCollection` to avoid creating a new collection every time -const collection = await client.getOrCreateCollection({ - name: "my_collection", -}); - -// switch `addRecords` to `upsertRecords` to avoid adding the same documents every time -await collection.upsert({ - documents: [ - "This is a document about pineapple", - "This is a document about oranges", - ], - ids: ["id1", "id2"], -}); - -const results = await collection.query({ - queryTexts: "This is a query document about florida", // Chroma will embed this for you - nResults: 2, // how many results to return -}); - -console.log(results); -``` - -{% /tab %} - -{% /tabs %} - -## 📚 Next steps - - - -- Read the [🧪 Usage Guide](/guides) to learn more about the API -- Learn how to [☁️ Deploy Chroma](/deployment) to a server -- Join Chroma's [Discord Community](https://discord.com/invite/MMeYNTmh3x) to ask questions and get help -- Follow Chroma on [Twitter (@trychroma)](https://twitter.com/trychroma) for updates - -{% hint style="info" %} diff --git a/docs/docs.trychroma.com/pages/guides/_sidenav.js b/docs/docs.trychroma.com/pages/guides/_sidenav.js deleted file mode 100644 index 9f65485a746..00000000000 --- a/docs/docs.trychroma.com/pages/guides/_sidenav.js +++ /dev/null @@ -1,24 +0,0 @@ -export const items = [ - // { - // title: 'Core Workflow', - // links: [ - // { href: '/guides/loading', children: 'Loading' }, - // { href: '/guides/splitting', children: 'Splitting' }, - // { href: '/guides/embedding', children: 'Embedding' }, - // { href: '/guides/querying', children: 'Querying' }, - // { href: '/guides/updating', children: 'Updating' }, - // { href: '/guides/deleting', children: 'Deleting' }, - // ] - // }, - { - title: 'Concepts', - links: [ - { href: '/guides/embeddings', children: '🧬 Embeddings' }, - { href: '/guides/multimodal', children: '🖼️ Multimodal' }, - // { href: '/guides/metadatas', children: 'Metadatas' }, - // { href: '/guides/documents', children: 'Documents' }, - // { href: '/guides/indexes', children: 'Indexes' }, - ] - }, - - ]; diff --git a/docs/docs.trychroma.com/pages/guides/adding.md b/docs/docs.trychroma.com/pages/guides/adding.md deleted file mode 100644 index 9c200e17d93..00000000000 --- a/docs/docs.trychroma.com/pages/guides/adding.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -title: Adding ---- diff --git a/docs/docs.trychroma.com/pages/guides/deleting.md b/docs/docs.trychroma.com/pages/guides/deleting.md deleted file mode 100644 index bdb543e6183..00000000000 --- a/docs/docs.trychroma.com/pages/guides/deleting.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -title: Deleting ---- diff --git a/docs/docs.trychroma.com/pages/guides/documents.md b/docs/docs.trychroma.com/pages/guides/documents.md deleted file mode 100644 index 4961f7aa7ce..00000000000 --- a/docs/docs.trychroma.com/pages/guides/documents.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -title: Documents ---- diff --git a/docs/docs.trychroma.com/pages/guides/embedding.md b/docs/docs.trychroma.com/pages/guides/embedding.md deleted file mode 100644 index 036c2099a80..00000000000 --- a/docs/docs.trychroma.com/pages/guides/embedding.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -title: Embedding ---- diff --git a/docs/docs.trychroma.com/pages/guides/indexes.md b/docs/docs.trychroma.com/pages/guides/indexes.md deleted file mode 100644 index d47f4bc6d8c..00000000000 --- a/docs/docs.trychroma.com/pages/guides/indexes.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -title: Indexes ---- diff --git a/docs/docs.trychroma.com/pages/guides/loading.md b/docs/docs.trychroma.com/pages/guides/loading.md deleted file mode 100644 index 27210b7cd0e..00000000000 --- a/docs/docs.trychroma.com/pages/guides/loading.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -title: Loading ---- diff --git a/docs/docs.trychroma.com/pages/guides/metadatas.md b/docs/docs.trychroma.com/pages/guides/metadatas.md deleted file mode 100644 index 22289cc2aa0..00000000000 --- a/docs/docs.trychroma.com/pages/guides/metadatas.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -title: Metadatas ---- diff --git a/docs/docs.trychroma.com/pages/guides/querying.md b/docs/docs.trychroma.com/pages/guides/querying.md deleted file mode 100644 index 64583b601bc..00000000000 --- a/docs/docs.trychroma.com/pages/guides/querying.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -title: Querying ---- diff --git a/docs/docs.trychroma.com/pages/guides/splitting.md b/docs/docs.trychroma.com/pages/guides/splitting.md deleted file mode 100644 index 42bb6567969..00000000000 --- a/docs/docs.trychroma.com/pages/guides/splitting.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -title: Splitting ---- diff --git a/docs/docs.trychroma.com/pages/guides/updating.md b/docs/docs.trychroma.com/pages/guides/updating.md deleted file mode 100644 index 0f40044eccd..00000000000 --- a/docs/docs.trychroma.com/pages/guides/updating.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -title: Updating ---- diff --git a/docs/docs.trychroma.com/pages/index.md b/docs/docs.trychroma.com/pages/index.md deleted file mode 100644 index b01a00835aa..00000000000 --- a/docs/docs.trychroma.com/pages/index.md +++ /dev/null @@ -1,92 +0,0 @@ ---- -title: Chroma ---- - -**Chroma is the AI-native open-source vector database**. Chroma makes it easy to build LLM apps by making knowledge, facts, and skills pluggable for LLMs. - -New to Chroma? [🔑 Getting Started](./getting-started). - -[![Discord](https://img.shields.io/discord/1073293645303795742?cacheSeconds=3600)](https://discord.gg/MMeYNTmh3x) -{% br %}{% /br %} -[![GitHub stars](https://img.shields.io/github/stars/chroma-core/chroma.svg?style=social&label=Star&maxAge=2400)](https://GitHub.com/chroma-core/chroma/stargazers/) - - -*** - - -![](/img/hrm4.svg) - -{% br %}{% /br %} - -Chroma gives you the tools to: - -- store embeddings and their metadata -- embed documents and queries -- search embeddings - -Chroma prioritizes: - -- simplicity and developer productivity -- it also happens to be very quick - -Chroma runs as a server and provides 1st party `Python` and `JavaScript/TypeScript` client SDKs. Check out the [Colab demo](https://colab.research.google.com/drive/1QEzFyqnoFxq7LUGyP1vzR4iLt9PpCDXv?usp=sharing). (yes, it can run in a Jupyter notebook 😄) - -Chroma is licensed under [Apache 2.0](https://github.com/chroma-core/chroma/blob/main/LICENSE) - -### Python -In Python, Chroma can run in a python script or as a server. - -```bash -pip install chromadb -``` - -### JavaScript -In JavaScript, use the Chroma JS/TS Client to connect to a Chroma server. - -{% codetabs customHeader="sh" %} -{% codetab label="yarn" %} -```bash {% codetab=true %} -yarn install chromadb chromadb-default-embed # [!code $] -``` -{% /codetab %} -{% codetab label="npm" %} -```bash {% codetab=true %} -npm install --save chromadb chromadb-default-embed # [!code $] -``` -{% /codetab %} -{% codetab label="pnpm" %} -```bash {% codetab=true %} -pnpm install chromadb chromadb-default-embed # [!code $] -``` -{% /codetab %} -{% /codetabs %} - - -Continue with the full [getting started guide](./getting-started). - - -*** - -### Language Clients - -{% special_table %} -{% /special_table %} - -| | client | -|--------------|---------------| -| Python | ✅ [`chromadb`](https://pypistats.org/packages/chromadb) (by Chroma) | -| Javascript | ✅ [`chromadb`](https://www.npmjs.com/package/chromadb) (by Chroma) | -| Ruby | ✅ [from @mariochavez](https://github.com/mariochavez/chroma) | -| Java | ✅ [from @t_azarov](https://github.com/amikos-tech/chromadb-java-client) | -| Go | ✅ [from @t_azarov](https://github.com/amikos-tech/chroma-go) | -| C# | ✅ [from @microsoft](https://github.com/microsoft/semantic-kernel/tree/main/dotnet/src/Connectors/Connectors.Memory.Chroma) | -| Rust | ✅ [from @Anush008](https://crates.io/crates/chromadb) | -| Elixir | ✅ [from @3zcurdia](https://hex.pm/packages/chroma/) | -| Dart | ✅ [from @davidmigloz](https://pub.dev/packages/chromadb) | -| PHP | ✅ [from @CodeWithKyrian](https://github.com/CodeWithKyrian/chromadb-php) | -| PHP (Laravel) | ✅ [from @HelgeSverre](https://github.com/helgeSverre/chromadb) | -| Clojure | ✅ [from @levand](https://github.com/levand/clojure-chroma-client) | | - -{% br %}{% /br %} - -We welcome [contributions](/contributing) for other languages! diff --git a/docs/docs.trychroma.com/pages/integrations/_sidenav.js b/docs/docs.trychroma.com/pages/integrations/_sidenav.js deleted file mode 100644 index 5feeda2d186..00000000000 --- a/docs/docs.trychroma.com/pages/integrations/_sidenav.js +++ /dev/null @@ -1,28 +0,0 @@ -export const items = [ - { - title: 'Embedding Models', - links: [ - { href: '/integrations/openai', children: 'OpenAI' }, - { href: '/integrations/cohere', children: 'Cohere' }, - { href: '/integrations/google-gemini', children: 'Google Gemini' }, - { href: '/integrations/hugging-face-server', children: 'HF Server' }, - { href: '/integrations/hugging-face', children: 'Hugging Face' }, - { href: '/integrations/instructor', children: 'Instructor' }, - { href: '/integrations/jinaai', children: 'JinaAI' }, - { href: '/integrations/roboflow', children: 'Roboflow' }, - { href: '/integrations/ollama', children: 'Ollama Embeddings' }, - ] - }, - { - title: 'Frameworks', - links: [ - { href: '/integrations/langchain', children: 'Langchain' }, - { href: '/integrations/llamaindex', children: 'LlamaIndex' }, - { href: '/integrations/braintrust', children: 'Braintrust' }, - { href: '/integrations/haystack', children: 'Haystack' }, - { href: '/integrations/openllmetry', children: 'OpenLLMetry' }, - { href: '/integrations/streamlit', children: 'Streamlit' }, - { href: '/integrations/openlit', children: 'OpenLIT' }, - ] - }, - ]; diff --git a/docs/docs.trychroma.com/pages/integrations/index.md b/docs/docs.trychroma.com/pages/integrations/index.md deleted file mode 100644 index 4561de28ef1..00000000000 --- a/docs/docs.trychroma.com/pages/integrations/index.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -title: 🔌 Integrations ---- - -*** - -### 🧬 Embedding Integrations - -Embeddings are the A.I-native way to represent any kind of data, making them the perfect fit for working with all kinds of A.I-powered tools and algorithms. They can represent text, images, and soon audio and video. There are many options for creating embeddings, whether locally using an installed library, or by calling an API. - -Chroma provides lightweight wrappers around popular embedding providers, making it easy to use them in your apps. You can set an embedding function when you create a Chroma collection, which will be used automatically, or you can call them directly yourself. - -{% special_table %} -{% /special_table %} - -| | Python | JS | -|--------------|-----------|---------------| -| [OpenAI](/integrations/openai) | ✅ | ✅ | -| [Google Gemini](/integrations/google-gemini) | ✅ | ✅ | -| [Cohere](/integrations/cohere) | ✅ | ✅ | -| [Hugging Face](/integrations/hugging-face) | ✅ | ➖ | -| [Instructor](/integrations/instructor) | ✅ | ➖ | -| [Hugging Face Embedding Server](/integrations/hugging-face-server) | ✅ | ✅ | -| [Jina AI](/integrations/jinaai) | ✅ | ✅ | -| [Roboflow](/integrations/roboflow) | ✅ | ➖ | -| [Ollama Embeddings](/integrations/ollama) | ✅ | ✅ | - - -*** - -### 🏗️ Framework Integrations - -Chroma maintains integrations with many popular tools. These tools can be used to define the business logic of an AI-native application, curate data, fine-tune embedding spaces and more. - -We welcome pull requests to add new Integrations to the community. - -{% special_table %} -{% /special_table %} - -| | Python | JS | -|--------------|-----------|---------------| -| [🦜️🔗 Langchain](/integrations/langchain) | ✅ | ✅ | -| [🦙 LlamaIndex](/integrations/llamaindex) | ✅ | ✅ | -| [Braintrust](/integrations/braintrust) | ✅ | ✅ | -| [🔭 OpenLLMetry](/integrations/openllmetry) | ✅ | 🔜 | -| [🎈 Streamlit](/integrations/streamlit) | ✅ | ➖ | -| [💙 Haystack](/integrations/haystack) | ✅ | ➖ | -| [🔭 OpenLIT](/integrations/openlit) | ✅ | 🔜 | diff --git a/docs/docs.trychroma.com/pages/integrations/llamaindex.md b/docs/docs.trychroma.com/pages/integrations/llamaindex.md deleted file mode 100644 index e6b120f7db4..00000000000 --- a/docs/docs.trychroma.com/pages/integrations/llamaindex.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: 🦙 LlamaIndex ---- - -- `LlamaIndex` [Vector Store page](https://docs.llamaindex.ai/en/stable/examples/vector_stores/ChromaIndexDemo.html) -- [Demo](https://github.com/run-llama/llama_index/blob/main/docs/docs/examples/data_connectors/ChromaDemo.ipynb) -- [Chroma Loader on Llamahub](https://llamahub.ai/l/vector_stores/llama-index-vector-stores-chroma) diff --git a/docs/docs.trychroma.com/pages/reference/_sidenav.js b/docs/docs.trychroma.com/pages/reference/_sidenav.js deleted file mode 100644 index cb1c8ed149b..00000000000 --- a/docs/docs.trychroma.com/pages/reference/_sidenav.js +++ /dev/null @@ -1,25 +0,0 @@ -export const items = [ - { - title: 'Python', - links: [ - { href: '/reference/py-client', children: 'Client' }, - { href: '/reference/py-collection', children: 'Collection' }, - ] - }, - { - title: 'JS', - links: [ - { href: '/reference/js-client', children: 'Client' }, - { href: '/reference/js-collection', children: 'Collection' }, - ] - }, - { - title: 'Other', - links: [ - { href: '/reference/docs', children: 'Docs Development' }, - { href: '/reference/cli', children: 'CLI' }, - // { href: '/reference/openapi', children: 'OpenAPI' }, - // { href: '/reference/architecture', children: 'Architecture' }, - ] - }, -]; diff --git a/docs/docs.trychroma.com/pages/reference/architecture.md b/docs/docs.trychroma.com/pages/reference/architecture.md deleted file mode 100644 index 4cdd86023dd..00000000000 --- a/docs/docs.trychroma.com/pages/reference/architecture.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -title: Architecture ---- diff --git a/docs/docs.trychroma.com/pages/reference/cheatsheet.md b/docs/docs.trychroma.com/pages/reference/cheatsheet.md deleted file mode 100644 index 13c3bfe7fc1..00000000000 --- a/docs/docs.trychroma.com/pages/reference/cheatsheet.md +++ /dev/null @@ -1,249 +0,0 @@ ---- -title: "📖 API Cheatsheet" ---- - -# 📖 API Cheatsheet - -{% note type="note" %} -This is a quick cheatsheet of the API. For full API docs, refer to the JS and Python docs in the sidebar. -{% /note %} - ---- - -{% tabs group="code-lang" hideContent=true %} -{% tab label="Python" %} -{% /tab %} -{% tab label="Javascript" %} -{% /tab %} -{% /tabs %} - ---- - -{% tabs group="code-lang" hideTabs=true %} -{% tab label="Python" %} - -## Initialize client - Python - -### In-memory chroma - -```python -import chromadb -client = chromadb.Client() -``` - -### In-memory chroma with saving/loading to disk - -In this mode, Chroma will persist data between sessions. On load - it will load up the data in the directory you specify. And as you add data - it will save to that directory. - -```python -import chromadb -client = chromadb.PersistentClient(path="/path/to/data") -``` - -### Run chroma just as a client to talk to a backend service - -You can run Chroma a standalone Chroma server using the Chroma command line. Run `chroma run --path /db_path` to run a server. - -Then update your API initialization and then use the API the same way as before. - -```python -import chromadb -chroma_client = chromadb.HttpClient(host="localhost", port=8000) -``` - -## Methods on Client - -### Methods related to Collections - -{% note type="note" title="Collection naming" %} -Collections are similar to AWS s3 buckets in their naming requirements because they are used in URLs in the REST API. Here's the [full list](/usage-guide#creating-inspecting-and-deleting-collections). -{% /note %} - -```python -# list all collections -client.list_collections() - -# make a new collection -collection = client.create_collection("testname") - -# get an existing collection -collection = client.get_collection("testname") - -# get a collection or create if it doesn't exist already -collection = client.get_or_create_collection("testname") - -# delete a collection -client.delete_collection("testname") -``` - -### Utility methods - -```python -# resets entire database - this *cant* be undone! -client.reset() - -# returns timestamp to check if service is up -client.heartbeat() -``` - -## Methods on Collection - -```python -# change the name or metadata on a collection -collection.modify(name="testname2") - -# get the number of items in a collection -collection.count() - -# add new items to a collection -# either one at a time -collection.add( - embeddings=[1.5, 2.9, 3.4], - metadatas={"uri": "img9.png", "style": "style1"}, - documents="doc1000101", - ids="uri9", -) -# or many, up to 100k+! -collection.add( - embeddings=[[1.5, 2.9, 3.4], [9.8, 2.3, 2.9]], - metadatas=[{"style": "style1"}, {"style": "style2"}], - ids=["uri9", "uri10"], -) -collection.add( - documents=["doc1000101", "doc288822"], - metadatas=[{"style": "style1"}, {"style": "style2"}], - ids=["uri9", "uri10"], -) - -# update items in a collection -collection.update() - -# upsert items. new items will be added, existing items will be updated. -collection.upsert( - ids=["id1", "id2", "id3", ...], - embeddings=[[1.1, 2.3, 3.2], [4.5, 6.9, 4.4], [1.1, 2.3, 3.2], ...], - metadatas=[{"chapter": "3", "verse": "16"}, {"chapter": "3", "verse": "5"}, {"chapter": "29", "verse": "11"}, ...], - documents=["doc1", "doc2", "doc3", ...], -) - -# get items from a collection -collection.get() - -# convenience, get first 5 items from a collection -collection.peek() - -# do nearest neighbor search to find similar embeddings or documents, supports filtering -collection.query( - query_embeddings=[[1.1, 2.3, 3.2], [5.1, 4.3, 2.2]], - n_results=2, - where={"style": "style2"} -) - -# delete items -collection.delete() -``` - -{% /tab %} -{% tab label="Javascript" %} - -### Run the backend - -Run `chroma run --path /db_path` to run the Chroma backend as a standalone server on your local computer. - -## Initialize client - JS - -```javascript -// CJS -const { ChromaClient } = require("chromadb"); - -// ESM -import { ChromaClient } from 'chromadb' - -const client = new ChromaClient(); -``` - -## Methods on Client - -### Methods related to Collections - -{% note type="note" title="Collection naming" %} -Collections are similar to AWS s3 buckets in their naming requirements because they are used in URLs in the REST API. Here's the [full list](/usage-guide#creating-inspecting-and-deleting-collections). -{% /note %} - -```javascript -// list all collections -await client.listCollections(); - -// make a new collection -const collection = await client.createCollection({ name: "testname" }); - -// get an existing collection -const collection = await client.getCollection({ name: "testname" }); - -// delete a collection -await client.deleteCollection({ name: "testname" }); -``` - -### Utility methods - -```javascript -// resets entire database - this *cant* be undone! -await client.reset(); -``` - -## Methods on Collection - -```javascript -// get the number of items in a collection -await collection.count() - -// add new items to a collection -// either one at a time -await collection.add({ - ids: "id1", - embeddings: [1.5, 2.9, 3.4], - metadatas: {"source": "my_source"}, - documents: "This is a document", -}) -// or many, up to 100k+! -await collection.add({ - ids: ["uri9", "uri10"], - embeddings: [[1.5, 2.9, 3.4], [9.8, 2.3, 2.9]], - metadatas: [{"style": "style1"}, {"style": "style2"}], - documents: ["This is a document", 'that is a document'] -}) -// including just documents -await collection.add({ - ids: ["uri9", "uri10"], - metadatas: [{"style": "style1"}, {"style": "style2"}], - documents: ["doc1000101", "doc288822"], -}) -// or use upsert, so records will be updated if they already exist -// (instead of throwing an error) -await collection.upsert({ - ids: "id1", - embeddings: [1.5, 2.9, 3.4], - metadatas: {"source": "my_source"}, - documents: "This is a document", -}) - -// get items from a collection -await collection.get() - -// convenience, get first 5 items from a collection -await collection.peek() - -// do nearest neighbor search to find similar embeddings or documents, supports filtering -await collection.query({ - queryEmbeddings: [[1.1, 2.3, 3.2], [5.1, 4.3, 2.2]], - nResults: 2, - where: {"style": "style2"} -}) - -// delete items -await collection.delete() - -``` - -{% /tab %} -{% /tabs %} diff --git a/docs/docs.trychroma.com/pages/reference/docs.md b/docs/docs.trychroma.com/pages/reference/docs.md deleted file mode 100644 index c977d54e97a..00000000000 --- a/docs/docs.trychroma.com/pages/reference/docs.md +++ /dev/null @@ -1,133 +0,0 @@ ---- -title: Docs Development ---- - -We welcome all contributions to improving our open source docs! - -Here are some ways you can help: -- Fix typos and grammar errors -- Improve the language and clarity of the docs -- Add missing information - -Great sections to contribute to you include: - -- [🔌 Integrations](/integrations) -- [☁️ Deployment options and Administration guides](/deployment) - -# How sidebars work - -The sidebar is generated from the `_sidenav.js` relative folder. For your page to show up, it has to be added to that list. - -The table of contents for any given page are collected from the header elements on that page. They are "tab-aware" and will only show headings that are visible. - -# Kitchen sink - -Please view this page on Github to see the underlying code. - -### Tabs - -{% tabs %} -{% tab label="one" %} -one -{% /tab %} -{% tab label="two" %} -two -{% /tab %} -{% /tabs %} - -### Code blocks and tabs - -Code block - -```javascript -console.log('Hello, world!'); -``` - -Code tabs -{% codetabs customHeader="sh" %} -{% codetab label="yarn" %} -```bash {% codetab=true %} -yarn install chromadb chromadb-default-embed # [!code $] -``` -{% /codetab %} -{% codetab label="npm" %} -```bash {% codetab=true %} -npm install --save chromadb chromadb-default-embed # [!code $] -``` -{% /codetab %} -{% /codetabs %} - -### Math - -{% math latexText="d = \\sum\\left(A_i-B_i\\right)^2" %}{% /math %} - - -### Tables - -#### Basic table - -| Name | Age | Location | -|-------|-----|----------| -| Alice | 24 | Seattle | - -#### Nicer looking table - -{% special_table %} -{% /special_table %} - -| Topic | -|--------------| -| [👀 Observability](/deployment/observability) | -| [✈️ Migration](/deployment/migration) | -| 🚧 *More Coming Soon* | - -### Lists - -- Item 1 -- Item 2 - -### Images - -![Alt text](https://source.unsplash.com/random/800x600) - -### Links - -[Click me](https://www.example.com) - -### Emojis - -🎉🎉🎉 - -### Alerts - -{% note type="default" title="Default" %} -I am alive -{% /note %} - -{% note type="caution" title="Caution" %} -I am alive -{% /note %} - -{% note type="warning" title="Warning" %} -I am alive -{% /note %} - -{% note type="tip" title="Tip" %} -I am alive -{% /note %} - - -### text - -# Heading 1 -## Heading 2 -### Heading 3 -#### Heading 4 - -### Horizontal rules - ---- - -### Code - -`code text` diff --git a/docs/docs.trychroma.com/pages/reference/openapi.md b/docs/docs.trychroma.com/pages/reference/openapi.md deleted file mode 100644 index b3a3ef2700d..00000000000 --- a/docs/docs.trychroma.com/pages/reference/openapi.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -title: OpenAPI ---- diff --git a/docs/docs.trychroma.com/pages/tabs.md b/docs/docs.trychroma.com/pages/tabs.md deleted file mode 100644 index 90073b6767c..00000000000 --- a/docs/docs.trychroma.com/pages/tabs.md +++ /dev/null @@ -1,56 +0,0 @@ ---- -title: Tabs demo ---- - - -{% tabs %} - -{% tab label="React" %} -React content goes here huh -{% /tab %} - -{% tab label="HTML" %} -HTML content goes here ok -{% /tab %} - -{% /tabs %} - - -{% tabs %} - -{% tab label="california" %} -ca babyyy -{% /tab %} - -{% tab label="newyork" %} -nyc babyyy -{% /tab %} - -{% /tabs %} - - -*** - -{% tabs group="code-lang" %} - -{% tab label="Python" %} -22 python -{% /tab %} - -{% tab label="Javascript" %} -22 javascript -{% /tab %} - -{% /tabs %} - -{% tabs group="code-lang" %} - -{% tab label="Python" %} -22 python -{% /tab %} - -{% tab label="Javascript" %} -22 javascript -{% /tab %} - -{% /tabs %} diff --git a/docs/docs.trychroma.com/pages/troubleshooting.md b/docs/docs.trychroma.com/pages/troubleshooting.md deleted file mode 100644 index e0f90539ead..00000000000 --- a/docs/docs.trychroma.com/pages/troubleshooting.md +++ /dev/null @@ -1,63 +0,0 @@ ---- -title: "🔍 Troubleshooting" ---- - -This page is a list of common gotchas or issues and how to fix them. - -If you don't see your problem listed here, please also search the [Github Issues](https://github.com/chroma-core/chroma/issues). - -## Using .get or .query, embeddings say `None` - -This is actually not an error. Embeddings are quite large and heavy to send back. Most application don't use the underlying embeddings and so, by default, chroma does not send them back. - -To send them back: add `include=["embeddings", "documents", "metadatas", "distances"]` to your query to return all information. - -For example: - -```python -results = collection.query( - query_texts="hello", - n_results=1, - include=["embeddings", "documents", "metadatas", "distances"], -) -``` - -{% note type="tip" %} -We may change `None` to something else to more clearly communicate why they were not returned. -{% /note %} - - -## Build error when running `pip install chromadb` - -If you encounter an error like this during setup - -``` -Failed to build hnswlib -ERROR: Could not build wheels for hnswlib, which is required to install pyproject.toml-based projects -``` - -Try these few tips from the [community](https://github.com/chroma-core/chroma/issues/221): - -1. If you get the error: `clang: error: the clang compiler does not support '-march=native'`, set this ENV variable, `export HNSWLIB_NO_NATIVE=1` -2. If on Mac, install/update xcode dev tools, `xcode-select --install` -3. If on Windows, try [these steps](https://github.com/chroma-core/chroma/issues/250#issuecomment-1540934224) - -## SQLite - -Chroma requires SQLite > 3.35, if you encounter issues with having too low of a SQLite version please try the following. - -1. Install the latest version of Python 3.10, sometimes lower versions of python are bundled with older versions of SQLite. -2. If you are on a Linux system, you can install pysqlite3-binary, `pip install pysqlite3-binary` and then override the default - sqlite3 library before running Chroma with the steps [here](https://gist.github.com/defulmere/8b9695e415a44271061cc8e272f3c300). - Alternatively you can compile SQLite from scratch and replace the library in your python installation with the latest version as documented [here](https://github.com/coleifer/pysqlite3#building-a-statically-linked-library). -3. If you are on Windows, you can manually download the latest version of SQLite from https://www.sqlite.org/download.html and - replace the DLL in your python installation's DLLs folder with the latest version. You can find your python installation path by running `os.path.dirname(sys.executable)` in python. -4. If you are using a Debian based Docker container, older Debian versions do not have an up to date SQLite, please use `bookworm` or higher. - -## Illegal instruction (core dumped) - -If you encounter an error like this during setup and are using Docker - you may have built the library on a machine with a different CPU architecture than the one you are running it on. Try rebuilding the Docker image on the machine you are running it on. - -## My data directory is too large - -If you were using Chroma prior to v0.5.6, you may be able to significantly shrink your database by [vacuuming it](/reference/cli#vacuuming). After vacuuming once, automatic pruning (a new feature in v0.5.6) is enabled and will keep your database size in check. diff --git a/docs/docs.trychroma.com/public/background.jpg b/docs/docs.trychroma.com/public/background.jpg new file mode 100644 index 00000000000..10c34447d82 Binary files /dev/null and b/docs/docs.trychroma.com/public/background.jpg differ diff --git a/docs/docs.trychroma.com/public/img/chroma-migrate.png b/docs/docs.trychroma.com/public/chroma-migrate.png similarity index 100% rename from docs/docs.trychroma.com/public/img/chroma-migrate.png rename to docs/docs.trychroma.com/public/chroma-migrate.png diff --git a/docs/docs.trychroma.com/public/chroma-wordmark-white-128.svg b/docs/docs.trychroma.com/public/chroma-wordmark-white-128.svg new file mode 100644 index 00000000000..e12af25d6f8 --- /dev/null +++ b/docs/docs.trychroma.com/public/chroma-wordmark-white-128.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/docs/docs.trychroma.com/public/chroma-workmark-color-128.svg b/docs/docs.trychroma.com/public/chroma-workmark-color-128.svg new file mode 100644 index 00000000000..a948b7351ca --- /dev/null +++ b/docs/docs.trychroma.com/public/chroma-workmark-color-128.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/docs/docs.trychroma.com/public/computer.svg b/docs/docs.trychroma.com/public/computer.svg new file mode 100644 index 00000000000..32ee61c5497 --- /dev/null +++ b/docs/docs.trychroma.com/public/computer.svg @@ -0,0 +1,745 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/docs.trychroma.com/public/img/concurrent-inserts.png b/docs/docs.trychroma.com/public/concurrent-inserts.png similarity index 100% rename from docs/docs.trychroma.com/public/img/concurrent-inserts.png rename to docs/docs.trychroma.com/public/concurrent-inserts.png diff --git a/docs/docs.trychroma.com/public/img/concurrent-queries.png b/docs/docs.trychroma.com/public/concurrent-queries.png similarity index 100% rename from docs/docs.trychroma.com/public/img/concurrent-queries.png rename to docs/docs.trychroma.com/public/concurrent-queries.png diff --git a/docs/docs.trychroma.com/public/img/concurrent-writes.png b/docs/docs.trychroma.com/public/concurrent-writes.png similarity index 100% rename from docs/docs.trychroma.com/public/img/concurrent-writes.png rename to docs/docs.trychroma.com/public/concurrent-writes.png diff --git a/docs/docs.trychroma.com/public/img/cpu-mean-query-latency.png b/docs/docs.trychroma.com/public/cpu-mean-query-latency.png similarity index 100% rename from docs/docs.trychroma.com/public/img/cpu-mean-query-latency.png rename to docs/docs.trychroma.com/public/cpu-mean-query-latency.png diff --git a/docs/docs.trychroma.com/public/img/after.gif b/docs/docs.trychroma.com/public/img/after.gif deleted file mode 100644 index 77004cf0486..00000000000 Binary files a/docs/docs.trychroma.com/public/img/after.gif and /dev/null differ diff --git a/docs/docs.trychroma.com/public/img/chroma.png b/docs/docs.trychroma.com/public/img/chroma.png deleted file mode 100644 index da7de3ddfa8..00000000000 Binary files a/docs/docs.trychroma.com/public/img/chroma.png and /dev/null differ diff --git a/docs/docs.trychroma.com/public/img/chroma.svg b/docs/docs.trychroma.com/public/img/chroma.svg deleted file mode 100644 index 64090685b9d..00000000000 --- a/docs/docs.trychroma.com/public/img/chroma.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/docs/docs.trychroma.com/public/img/favicon.ico b/docs/docs.trychroma.com/public/img/favicon.ico deleted file mode 100644 index 53ab6af74e7..00000000000 Binary files a/docs/docs.trychroma.com/public/img/favicon.ico and /dev/null differ diff --git a/docs/docs.trychroma.com/public/img/glitch.gif b/docs/docs.trychroma.com/public/img/glitch.gif deleted file mode 100644 index c2fe3e830d2..00000000000 Binary files a/docs/docs.trychroma.com/public/img/glitch.gif and /dev/null differ diff --git a/docs/docs.trychroma.com/public/img/hrm4.svg b/docs/docs.trychroma.com/public/img/hrm4.svg deleted file mode 100644 index 1accb742cad..00000000000 --- a/docs/docs.trychroma.com/public/img/hrm4.svg +++ /dev/null @@ -1,56 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/docs.trychroma.com/public/img/pip.png b/docs/docs.trychroma.com/public/img/pip.png deleted file mode 100644 index 4e618b85270..00000000000 Binary files a/docs/docs.trychroma.com/public/img/pip.png and /dev/null differ diff --git a/docs/docs.trychroma.com/public/img/svg_fast.svg b/docs/docs.trychroma.com/public/img/svg_fast.svg deleted file mode 100644 index ae9c6d78a16..00000000000 --- a/docs/docs.trychroma.com/public/img/svg_fast.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/docs/docs.trychroma.com/public/img/svg_fast2.svg b/docs/docs.trychroma.com/public/img/svg_fast2.svg deleted file mode 100644 index 001c49adcf8..00000000000 --- a/docs/docs.trychroma.com/public/img/svg_fast2.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/docs/docs.trychroma.com/public/img/svg_feature.svg b/docs/docs.trychroma.com/public/img/svg_feature.svg deleted file mode 100644 index a2d8962fe3e..00000000000 --- a/docs/docs.trychroma.com/public/img/svg_feature.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/docs/docs.trychroma.com/public/img/svg_free.svg b/docs/docs.trychroma.com/public/img/svg_free.svg deleted file mode 100644 index 7988404871a..00000000000 --- a/docs/docs.trychroma.com/public/img/svg_free.svg +++ /dev/null @@ -1,196 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/docs.trychroma.com/public/img/svg_simple.svg b/docs/docs.trychroma.com/public/img/svg_simple.svg deleted file mode 100644 index 78ef52aa95e..00000000000 --- a/docs/docs.trychroma.com/public/img/svg_simple.svg +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - diff --git a/docs/docs.trychroma.com/public/img/svg_simple2.svg b/docs/docs.trychroma.com/public/img/svg_simple2.svg deleted file mode 100644 index 34e60e7c6f7..00000000000 --- a/docs/docs.trychroma.com/public/img/svg_simple2.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/docs/docs.trychroma.com/public/img/insert-latency.png b/docs/docs.trychroma.com/public/insert-latency.png similarity index 100% rename from docs/docs.trychroma.com/public/img/insert-latency.png rename to docs/docs.trychroma.com/public/insert-latency.png diff --git a/docs/docs.trychroma.com/public/investors.png b/docs/docs.trychroma.com/public/investors.png new file mode 100644 index 00000000000..f2cb8ae1326 Binary files /dev/null and b/docs/docs.trychroma.com/public/investors.png differ diff --git a/docs/docs.trychroma.com/public/img/openllmetry.png b/docs/docs.trychroma.com/public/openllmetry.png similarity index 100% rename from docs/docs.trychroma.com/public/img/openllmetry.png rename to docs/docs.trychroma.com/public/openllmetry.png diff --git a/docs/docs.trychroma.com/public/python.svg b/docs/docs.trychroma.com/public/python.svg new file mode 100644 index 00000000000..a16973b118c --- /dev/null +++ b/docs/docs.trychroma.com/public/python.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/docs.trychroma.com/public/img/query-latency.png b/docs/docs.trychroma.com/public/query-latency.png similarity index 100% rename from docs/docs.trychroma.com/public/img/query-latency.png rename to docs/docs.trychroma.com/public/query-latency.png diff --git a/docs/docs.trychroma.com/public/img/team.JPG b/docs/docs.trychroma.com/public/team.JPG similarity index 100% rename from docs/docs.trychroma.com/public/img/team.JPG rename to docs/docs.trychroma.com/public/team.JPG diff --git a/docs/docs.trychroma.com/public/typescript.svg b/docs/docs.trychroma.com/public/typescript.svg new file mode 100644 index 00000000000..3acb58ca104 --- /dev/null +++ b/docs/docs.trychroma.com/public/typescript.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/docs.trychroma.com/public/x-logo.svg b/docs/docs.trychroma.com/public/x-logo.svg new file mode 100644 index 00000000000..437e2bfddbb --- /dev/null +++ b/docs/docs.trychroma.com/public/x-logo.svg @@ -0,0 +1,3 @@ + + + diff --git a/docs/docs.trychroma.com/pydoc-markdown.yml b/docs/docs.trychroma.com/pydoc-markdown.yml index 6d6437e729c..9c8d5a1a2fe 100644 --- a/docs/docs.trychroma.com/pydoc-markdown.yml +++ b/docs/docs.trychroma.com/pydoc-markdown.yml @@ -14,7 +14,7 @@ processors: - type: crossref renderer: type: docusaurus - docs_base_path: pages + docs_base_path: pages-old relative_output_path: reference relative_sidebar_path: sidebar.json sidebar_top_level_label: 'Reference Docs' diff --git a/docs/docs.trychroma.com/scripts/jsDocs.sh b/docs/docs.trychroma.com/scripts/jsDocs.sh index 2e52763188a..fc4618f3e30 100644 --- a/docs/docs.trychroma.com/scripts/jsDocs.sh +++ b/docs/docs.trychroma.com/scripts/jsDocs.sh @@ -1,4 +1,4 @@ -# cleanup old pages +# cleanup old pages-old rm pages/reference/js-client.md rm pages/reference/js-collection.md diff --git a/docs/docs.trychroma.com/scripts/pythonDocs.sh b/docs/docs.trychroma.com/scripts/pythonDocs.sh index b7b2257467e..e6905f819f8 100644 --- a/docs/docs.trychroma.com/scripts/pythonDocs.sh +++ b/docs/docs.trychroma.com/scripts/pythonDocs.sh @@ -71,5 +71,5 @@ sed -i.bak -e '/@abstractmethod/d' "$file_out" rm "${file2}.bak" rm "${file_out}.bak" -rm pages/reference/Collection.md -rm pages/reference/sidebar.json +rm pages-old/reference/Collection.md +rm pages-old/reference/sidebar.json diff --git a/docs/docs.trychroma.com/tailwind.config.js b/docs/docs.trychroma.com/tailwind.config.js deleted file mode 100644 index 1fd88772f6e..00000000000 --- a/docs/docs.trychroma.com/tailwind.config.js +++ /dev/null @@ -1,81 +0,0 @@ -/** @type {import('tailwindcss').Config} */ -module.exports = { - darkMode: ["class", '[data-theme="dark"]'], - content: [ - "./pages/**/*.{ts,tsx}", - "./components/**/*.{ts,tsx}", - "./app/**/*.{ts,tsx}", - "./src/**/*.{ts,tsx}", - ], - prefix: "", - theme: { - container: { - center: true, - padding: "2rem", - screens: { - "2xl": "1400px", - }, - }, - extend: { - fontFamily: { - sans: ["var(--font-inter)"], - mono: ["var(--font-ibm-plex-mono)"], - }, - colors: { - border: "hsl(var(--border))", - input: "hsl(var(--input))", - ring: "hsl(var(--ring))", - background: "hsl(var(--background))", - foreground: "hsl(var(--foreground))", - primary: { - DEFAULT: "hsl(var(--primary))", - foreground: "hsl(var(--primary-foreground))", - }, - secondary: { - DEFAULT: "hsl(var(--secondary))", - foreground: "hsl(var(--secondary-foreground))", - }, - destructive: { - DEFAULT: "hsl(var(--destructive))", - foreground: "hsl(var(--destructive-foreground))", - }, - muted: { - DEFAULT: "hsl(var(--muted))", - foreground: "hsl(var(--muted-foreground))", - }, - accent: { - DEFAULT: "hsl(var(--accent))", - foreground: "hsl(var(--accent-foreground))", - }, - popover: { - DEFAULT: "hsl(var(--popover))", - foreground: "hsl(var(--popover-foreground))", - }, - card: { - DEFAULT: "hsl(var(--card))", - foreground: "hsl(var(--card-foreground))", - }, - }, - borderRadius: { - lg: "var(--radius)", - md: "calc(var(--radius) - 2px)", - sm: "calc(var(--radius) - 4px)", - }, - keyframes: { - "accordion-down": { - from: { height: "0" }, - to: { height: "var(--radix-accordion-content-height)" }, - }, - "accordion-up": { - from: { height: "var(--radix-accordion-content-height)" }, - to: { height: "0" }, - }, - }, - animation: { - "accordion-down": "accordion-down 0.2s ease-out", - "accordion-up": "accordion-up 0.2s ease-out", - }, - }, - }, - plugins: [require("tailwindcss-animate")], -}; diff --git a/docs/docs.trychroma.com/tailwind.config.ts b/docs/docs.trychroma.com/tailwind.config.ts new file mode 100644 index 00000000000..9ef9c63bc50 --- /dev/null +++ b/docs/docs.trychroma.com/tailwind.config.ts @@ -0,0 +1,29 @@ +import type { Config } from "tailwindcss"; + +const config: Config = { + darkMode: ["class"], + content: [ + "./pages/**/*.{js,ts,jsx,tsx,mdx,md}", + "./components/**/*.{js,ts,jsx,tsx,mdx,md}", + "./app/**/*.{js,ts,jsx,tsx,mdx,md}", + "./markdoc/**/*.{md,mdx}", + ], + theme: { + extend: { + colors: { + background: "var(--background)", + foreground: "var(--foreground)", + "chroma-orange": "#FF6446", + }, + borderRadius: { + lg: "var(--radius)", + md: "calc(var(--radius) - 2px)", + sm: "calc(var(--radius) - 4px)", + }, + typography: {}, + }, + }, + // eslint-disable-next-line @typescript-eslint/no-require-imports + plugins: [require("tailwindcss-animate"), require("@tailwindcss/typography")], +}; +export default config; diff --git a/docs/docs.trychroma.com/tsconfig.json b/docs/docs.trychroma.com/tsconfig.json index b9bb3eaa84f..d81d4ee14e7 100644 --- a/docs/docs.trychroma.com/tsconfig.json +++ b/docs/docs.trychroma.com/tsconfig.json @@ -1,6 +1,5 @@ { "compilerOptions": { - "target": "es5", "lib": [ "dom", "dom.iterable", @@ -8,23 +7,32 @@ ], "allowJs": true, "skipLibCheck": true, - "strict": false, - "forceConsistentCasingInFileNames": true, + "strict": true, "noEmit": true, - "incremental": true, "esModuleInterop": true, "module": "esnext", - "moduleResolution": "node", + "moduleResolution": "bundler", "resolveJsonModule": true, "isolatedModules": true, - "jsx": "preserve" + "jsx": "preserve", + "incremental": true, + "plugins": [ + { + "name": "next" + } + ], + "paths": { + "@/*": [ + "./*" + ] + }, + "target": "ES2017" }, "include": [ "next-env.d.ts", "**/*.ts", "**/*.tsx", - "markdoc/config.js", - "../../clients/js/src" + ".next/types/**/*.ts" ], "exclude": [ "node_modules"